diff options
-rw-r--r-- | libbuild2/test/script/parser+command-if.test.testscript | 9 | ||||
-rw-r--r-- | libbuild2/test/script/parser.cxx | 32 | ||||
-rw-r--r-- | libbuild2/test/script/parser.hxx | 3 |
3 files changed, 36 insertions, 8 deletions
diff --git a/libbuild2/test/script/parser+command-if.test.testscript b/libbuild2/test/script/parser+command-if.test.testscript index bfca9e8..0b72b4a 100644 --- a/libbuild2/test/script/parser+command-if.test.testscript +++ b/libbuild2/test/script/parser+command-if.test.testscript @@ -325,6 +325,15 @@ testscript:2:1: error: 'end' without preceding 'if' EOE + : without-if-semi + : + $* <<EOI 2>>EOE != 0 + cmd; + end + EOI + testscript:2:1: error: 'end' without preceding 'if' + EOE + : before { : semi diff --git a/libbuild2/test/script/parser.cxx b/libbuild2/test/script/parser.cxx index f663c11..b29ced9 100644 --- a/libbuild2/test/script/parser.cxx +++ b/libbuild2/test/script/parser.cxx @@ -296,13 +296,15 @@ namespace build2 // recognize it is to parse the if line). // // If one is true then only parse one line returning an indication of - // whether the line ended with a semicolon. + // whether the line ended with a semicolon. If if_line is true then this + // line can be an if-else construct flow control line (else, end, etc). // bool parser:: pre_parse_line (token& t, type& tt, optional<description>& d, lines* ls, - bool one) + bool one, + bool if_line) { // enter: next token is peeked at (type in tt) // leave: newline @@ -415,12 +417,19 @@ namespace build2 break; } - case line_type::cmd_if: - case line_type::cmd_ifn: case line_type::cmd_elif: case line_type::cmd_elifn: case line_type::cmd_else: case line_type::cmd_end: + { + if (!if_line) + { + fail (t) << lt << " without preceding 'if'"; + } + } + // Fall through. + case line_type::cmd_if: + case line_type::cmd_ifn: next (t, tt); // Skip to start of command. // Fall through. case line_type::cmd: @@ -511,7 +520,7 @@ namespace build2 case line_type::cmd_else: case line_type::cmd_end: { - fail (ll) << lt << " without preceding 'if'" << endf; + assert (false); // Should have been failed earlier. } case line_type::cmd_if: case line_type::cmd_ifn: @@ -780,7 +789,12 @@ namespace build2 // the next iteration. // optional<description> td; - bool semi (pre_parse_line (t, (tt = pt), td, &ls, true)); + bool semi (pre_parse_line (t, (tt = pt), + td, + &ls, + true /* one */, + true /* if_line */)); + assert (ls.size () == 1 && ls.back ().type == lt); assert (tt == type::newline); @@ -856,7 +870,11 @@ namespace build2 size_t i (ls.size ()); optional<description> td; - bool semi (pre_parse_line (t, tt, td, &ls, true)); + bool semi (pre_parse_line (t, tt, + td, + &ls, + true /* one */, + true /* if_line */)); assert (tt == type::newline); line_type lt (ls[i].type); diff --git a/libbuild2/test/script/parser.hxx b/libbuild2/test/script/parser.hxx index aa64943..0c467a5 100644 --- a/libbuild2/test/script/parser.hxx +++ b/libbuild2/test/script/parser.hxx @@ -59,7 +59,8 @@ namespace build2 pre_parse_line (token&, token_type&, optional<description>&, lines* = nullptr, - bool one = false); + bool one = false, + bool if_line = false); bool pre_parse_if_else (token&, token_type&, |