diff options
-rw-r--r-- | build2/test/script/lexer.cxx | 22 | ||||
-rw-r--r-- | build2/test/script/parser.cxx | 48 | ||||
-rw-r--r-- | unit-tests/test/script/lexer/description-line.test | 8 | ||||
-rw-r--r-- | unit-tests/test/script/parser/description.test | 44 | ||||
-rw-r--r-- | unit-tests/test/script/parser/setup-teardown.test | 8 |
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 |