aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2016-10-28 13:01:04 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2016-11-04 09:26:36 +0200
commit08ae9246421cf2b7269dc09dab2dbd5dc5d0817a (patch)
tree727dcf6be0a382a3a41f3ebf63d624ab893c786d
parentfac9e22e90591b4c60d0e13c10c3abccf8c96a0f (diff)
Add tests and fixes for trailing description support
-rw-r--r--build2/test/script/lexer.cxx22
-rw-r--r--build2/test/script/parser.cxx48
-rw-r--r--unit-tests/test/script/lexer/description-line.test8
-rw-r--r--unit-tests/test/script/parser/description.test44
-rw-r--r--unit-tests/test/script/parser/setup-teardown.test8
5 files changed, 104 insertions, 26 deletions
diff --git a/build2/test/script/lexer.cxx b/build2/test/script/lexer.cxx
index 8b647dc..a9b7d56 100644
--- a/build2/test/script/lexer.cxx
+++ b/build2/test/script/lexer.cxx
@@ -407,20 +407,30 @@ namespace build2
token lexer::
next_description ()
{
- xchar c (get ());
+ xchar c (peek ());
+
+ if (eos (c))
+ fail (c) << "expected newline at the end of description line";
uint64_t ln (c.line), cn (c.column);
+
+ if (c == '\n')
+ {
+ get ();
+ state_.pop (); // Expire the description mode.
+ return token (type::newline, false, ln, cn, token_printer);
+ }
+
string lexeme;
// For now no line continutions though we could support them.
//
- for (; !eos (c) && c != '\n'; c = get ())
+ for (; !eos (c) && c != '\n'; c = peek ())
+ {
+ get ();
lexeme += c;
+ }
- if (eos (c))
- fail (c) << "expected newline at the end of description line";
-
- state_.pop (); // Expire the description mode.
return token (move (lexeme), false, false, ln, cn);
}
diff --git a/build2/test/script/parser.cxx b/build2/test/script/parser.cxx
index a6b8e50..e714665 100644
--- a/build2/test/script/parser.cxx
+++ b/build2/test/script/parser.cxx
@@ -350,13 +350,20 @@ namespace build2
mode (lexer_mode::description_line);
next (t, tt);
- assert (tt == type::word);
- const string& l (t.value);
+ // If it is empty, then we get newline right away.
+ //
+ const string& l (tt == type::word ? t.value : string ());
+
+ if (tt == type::word)
+ next (t, tt); // Get newline.
+
+ assert (tt == type::newline);
- // If this is the first line, then get the "strip prefix", i.e., the
- // beginning of the line that contains only whitespaces. If the
- // subsequent lines start with the same prefix, then we strip it.
+ // If this is the first line, then get the "strip prefix", i.e.,
+ // the beginning of the line that contains only whitespaces. If
+ // the subsequent lines start with the same prefix, then we strip
+ // it.
//
if (ln == 1)
{
@@ -1099,6 +1106,7 @@ namespace build2
case type::equal:
case type::not_equal:
case type::semi:
+ case type::colon:
case type::newline:
{
done = true;
@@ -1424,23 +1432,27 @@ namespace build2
mode (lexer_mode::description_line);
next (t, tt);
- assert (tt == type::word);
-
- string l (move (t.value));
- trim (l); // Strip leading/trailing whitespaces.
- // Decide whether this is id or summary.
+ // If it is empty, then we get newline right away.
//
- auto& d (*(r.second = description ()));
- (l.find_first_of (" \t") == string::npos ? d.id : d.summary) =
- move (l);
+ if (tt == type::word)
+ {
+ string l (move (t.value));
+ trim (l); // Strip leading/trailing whitespaces.
- if (d.empty ())
- fail (loc) << "empty description";
+ // Decide whether this is id or summary.
+ //
+ auto& d (*(r.second = description ()));
+ (l.find_first_of (" \t") == string::npos ? d.id : d.summary) =
+ move (l);
- //@@ No newline token!
- //
- tt = type::newline;
+ next (t, tt); // Get newline.
+ }
+
+ assert (tt == type::newline);
+
+ if (r.second->empty ())
+ fail (loc) << "empty description";
}
else
{
diff --git a/unit-tests/test/script/lexer/description-line.test b/unit-tests/test/script/lexer/description-line.test
index f0f0c9f..1d317eb 100644
--- a/unit-tests/test/script/lexer/description-line.test
+++ b/unit-tests/test/script/lexer/description-line.test
@@ -2,16 +2,20 @@ test.arguments += description-line
$* <" foo bar " >>EOO # full
' foo bar '
+<newline>
EOO
$* <" " >>EOO # space
' '
+<newline>
EOO
$* <"" >>EOO # empty
-''
+<newline>
EOO
-$* <:"foo" 2>>EOE != 0 # eof
+$* <:"foo" >>EOO 2>>EOE != 0 # eof
+'foo'
+EOO
stdin:1:4: error: expected newline at the end of description line
EOE
diff --git a/unit-tests/test/script/parser/description.test b/unit-tests/test/script/parser/description.test
index 881cb5b..c2c441b 100644
--- a/unit-tests/test/script/parser/description.test
+++ b/unit-tests/test/script/parser/description.test
@@ -6,6 +6,13 @@ EOI
cmd
EOO
+$* <<EOI >>EOO # trail-id
+cmd : foo
+EOI
+: id:foo
+cmd
+EOO
+
$* <<EOI >>EOO # summary
: foo bar
cmd
@@ -14,6 +21,13 @@ EOI
cmd
EOO
+$* <<EOI >>EOO # trail-summary
+cmd: foo bar
+EOI
+: sm:foo bar
+cmd
+EOO
+
$* <<EOI >>EOO # id-summary
: foo-bar
: foo bar
@@ -131,6 +145,36 @@ EOI
cmd
EOO
+$* <<EOI >>EOO # trail-compound
+cmd1;
+cmd2: foo
+EOI
+: id:foo
+cmd1
+cmd2
+EOO
+
+$* <<EOI 2>>EOE != 0 # empty
+:
+:
+cmd
+EOI
+testscript:1:1: error: empty description
+EOE
+
+$* <<EOI 2>>EOE != 0 # trail-empty
+cmd:
+EOI
+testscript:1:4: error: empty description
+EOE
+
+$* <<EOI 2>>EOE != 0 # both
+: foo
+cmd : bar
+EOI
+testscript:2:1: error: both leading and trailing description
+EOE
+
# Legal places for a description.
#
$* <<EOI >>EOO # legal-var
diff --git a/unit-tests/test/script/parser/setup-teardown.test b/unit-tests/test/script/parser/setup-teardown.test
index 57528ad..5d30ed4 100644
--- a/unit-tests/test/script/parser/setup-teardown.test
+++ b/unit-tests/test/script/parser/setup-teardown.test
@@ -2,10 +2,18 @@ $* <"+cmd;" 2>>EOE != 0 # semi-after-setup
testscript:1:5: error: ';' after setup command
EOE
+$* <"+cmd:" 2>>EOE != 0 # colon-after-setup
+testscript:1:5: error: ':' after setup command
+EOE
+
$* <"-cmd;" 2>>EOE != 0 # semi-after-tdown
testscript:1:5: error: ';' after teardown command
EOE
+$* <"-cmd:" 2>>EOE != 0 # colon-after-tdown
+testscript:1:5: error: ':' after teardown command
+EOE
+
$* <<EOI 2>>EOE != 0 # setup-in-test
cmd;
+cmd