diff options
-rw-r--r-- | build2/test/script/lexer.cxx | 14 | ||||
-rw-r--r-- | build2/test/script/parser.cxx | 36 | ||||
-rw-r--r-- | build2/test/script/token | 4 | ||||
-rw-r--r-- | build2/test/script/token.cxx | 5 | ||||
-rw-r--r-- | unit-tests/test/script/lexer/command-line.test | 13 | ||||
-rw-r--r-- | unit-tests/test/script/lexer/script-line.test | 18 | ||||
-rw-r--r-- | unit-tests/test/script/parser/cleanup.test | 48 |
7 files changed, 102 insertions, 36 deletions
diff --git a/build2/test/script/lexer.cxx b/build2/test/script/lexer.cxx index a9b7d56..b7a9f78 100644 --- a/build2/test/script/lexer.cxx +++ b/build2/test/script/lexer.cxx @@ -264,13 +264,21 @@ namespace build2 // case '&': { - if (peek () == '&') + xchar p (peek ()); + + if (p == '?' || p == '!' || p == '&') { get (); - return make_token (type::log_and); + + switch (p) + { + case '?': return make_token (type::clean_maybe); + case '!': return make_token (type::clean_never); + case '&': return make_token (type::log_and); + } } else - return make_token (type::clean); + return make_token (type::clean_always); } // < // diff --git a/build2/test/script/parser.cxx b/build2/test/script/parser.cxx index fc40fd0..7fb0608 100644 --- a/build2/test/script/parser.cxx +++ b/build2/test/script/parser.cxx @@ -807,6 +807,7 @@ namespace build2 pending p (pending::program); bool nn (false); // True if pending here-{str,doc} is "no-newline". bool app (false); // True if to append to pending file. + cleanup_type ct; // Pending cleanup type. // Ordered sequence of here-document redirects that we can expect to // see after the command line. @@ -823,7 +824,7 @@ namespace build2 // to program arguments by default. // auto add_word = - [&c, &p, &nn, &app, &hd, this] (string&& w, const location& l) + [&c, &p, &nn, &app, &ct, &hd, this] (string&& w, const location& l) { auto add_merge = [&l, this] (redirect& r, const string& w, int fd) { @@ -913,7 +914,8 @@ namespace build2 case pending::clean: { c.cleanups.push_back ( - {cleanup_type::always, parse_path (move (w), "cleanup path")}); + {ct, parse_path (move (w), "cleanup path")}); + break; } } @@ -1092,6 +1094,20 @@ namespace build2 } }; + // Set pending cleanup type. + // + auto parse_clean = [&p, &ct] (type tt) + { + switch (tt) + { + case type::clean_always: ct = cleanup_type::always; break; + case type::clean_maybe: ct = cleanup_type::maybe; break; + case type::clean_never: ct = cleanup_type::never; break; + } + + p = pending::clean; + }; + const location ll (get_location (t)); // Line location. // Keep parsing chunks of the command line until we see one of the @@ -1136,7 +1152,9 @@ namespace build2 case type::out_file: case type::out_file_app: - case type::clean: + case type::clean_always: + case type::clean_maybe: + case type::clean_never: { if (pre_parse_) { @@ -1206,9 +1224,11 @@ namespace build2 break; } - case type::clean: + case type::clean_always: + case type::clean_maybe: + case type::clean_never: { - p = pending::clean; + parse_clean (tt); break; } @@ -1369,9 +1389,11 @@ namespace build2 break; } - case type::clean: + case type::clean_always: + case type::clean_maybe: + case type::clean_never: { - p = pending::clean; + parse_clean (tt); break; } diff --git a/build2/test/script/token b/build2/test/script/token index a1374fe..d4f6eec 100644 --- a/build2/test/script/token +++ b/build2/test/script/token @@ -30,7 +30,9 @@ namespace build2 minus, // - pipe, // | - clean, // & + clean_always, // & + clean_maybe, // &? + clean_never, // &! log_and, // && log_or, // || diff --git a/build2/test/script/token.cxx b/build2/test/script/token.cxx index 1cd0859..79e64de 100644 --- a/build2/test/script/token.cxx +++ b/build2/test/script/token.cxx @@ -26,8 +26,11 @@ namespace build2 case token_type::plus: os << q << '+' << q; break; case token_type::minus: os << q << '-' << q; break; + case token_type::clean_always: os << q << '&' << q; break; + case token_type::clean_maybe: os << q << "&?" << q; break; + case token_type::clean_never: os << q << "&!" << q; break; + case token_type::pipe: os << q << '|' << q; break; - case token_type::clean: os << q << '&' << q; break; case token_type::log_and: os << q << "&&" << q; break; case token_type::log_or: os << q << "||" << q; break; diff --git a/unit-tests/test/script/lexer/command-line.test b/unit-tests/test/script/lexer/command-line.test index bc791dc..acb7d1d 100644 --- a/unit-tests/test/script/lexer/command-line.test +++ b/unit-tests/test/script/lexer/command-line.test @@ -118,12 +118,17 @@ $* <:"1>>>&a b" >>EOO # out-file-app-redirect 'a b' EOO -$* <:"&file" >>EOO # file-cleanup +$* <:"&file" >>EOO # cleanup-always & 'file' EOO -$* <:"&dir/" >>EOO # dir-cleanup -& -'dir/' +$* <:"&?file" >>EOO # cleanup-maybe +&? +'file' +EOO + +$* <:"&!file" >>EOO # cleanup-never +&! +'file' EOO diff --git a/unit-tests/test/script/lexer/script-line.test b/unit-tests/test/script/lexer/script-line.test index 96eb19c..44f6002 100644 --- a/unit-tests/test/script/lexer/script-line.test +++ b/unit-tests/test/script/lexer/script-line.test @@ -112,11 +112,23 @@ $* <"cmd <<<in >>>out 2>>>&err" >>EOO # file-redirect <newline> EOO -$* <"cmd &file &dir/" >>EOO # cleanup +$* <"cmd &file" >>EOO # cleanup-always 'cmd' & 'file' -& -'dir/' +<newline> +EOO + +$* <"cmd &?file" >>EOO # cleanup-maybe +'cmd' +&? +'file' +<newline> +EOO + +$* <"cmd &!file" >>EOO # cleanup-never +'cmd' +&! +'file' <newline> EOO diff --git a/unit-tests/test/script/parser/cleanup.test b/unit-tests/test/script/parser/cleanup.test index 7fe746d..76614e3 100644 --- a/unit-tests/test/script/parser/cleanup.test +++ b/unit-tests/test/script/parser/cleanup.test @@ -1,35 +1,49 @@ -$* <<EOI >>EOO # file-dir -cmd &file &dir/ +: always +: +$* <<EOI >>EOO +cmd &file EOI -cmd &file &dir/ +cmd &file EOO -$* <<EOI >>EOO # quote-file-dir -cmd &"f ile" &"d ir/" +: maybe +: +$* <<EOI >>EOO +cmd &?file EOI -cmd &"f ile" &"d ir/" +cmd &?file EOO -$* <<EOI >>EOO # dup-file -cmd &file &file +: never +: +$* <<EOI >>EOO +cmd &!file EOI -cmd &file &file +cmd &!file EOO -$* <<EOI 2>>EOE != 0 # file-fail1 +: empty +: +$* <<EOI 2>>EOE != 0 +cmd &"" +EOI +testscript:1:6: error: empty cleanup path +EOE + +: missed-before-token +: Path missed before command next token +: +$* <<EOI 2>>EOE != 0 cmd & >file EOI testscript:1:7: error: missing cleanup path EOE -$* <<EOI 2>>EOE != 0 # file-fail2 +: missed-before-end +: Test path missed before end of command +: +$* <<EOI 2>>EOE != 0 cmd & EOI testscript:1:6: error: missing cleanup path EOE - -$* <<EOI 2>>EOE != 0 # file-fail3 -cmd &"" -EOI -testscript:1:6: error: empty cleanup path -EOE |