aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--build2/test/script/parser.cxx66
-rw-r--r--build2/test/script/script2
-rw-r--r--build2/test/script/script.cxx27
-rw-r--r--unit-tests/test/script/lexer/command-line.test10
-rw-r--r--unit-tests/test/script/lexer/script-line.test9
-rw-r--r--unit-tests/test/script/parser/buildfile4
-rw-r--r--unit-tests/test/script/parser/cleanup.test35
7 files changed, 125 insertions, 28 deletions
diff --git a/build2/test/script/parser.cxx b/build2/test/script/parser.cxx
index a3f2f00..152f1f0 100644
--- a/build2/test/script/parser.cxx
+++ b/build2/test/script/parser.cxx
@@ -581,7 +581,8 @@ namespace build2
err_merge,
err_string,
err_document,
- err_file
+ err_file,
+ clean
};
pending p (pending::program);
bool nn (false); // True if pending here-{str,doc} is "no-newline".
@@ -632,23 +633,30 @@ namespace build2
hd.push_back (here_doc {&r, move (w), nn});
};
- auto add_file =
- [&app, &l, this] (redirect& r, const char* n, string&& w)
+ auto parse_path = [&l, this] (const char* n, string&& w)
{
try
{
- r.file.path = path (move (w));
+ path p (move (w));
- if (r.file.path.empty ())
- fail (l) << "empty " << n << " redirect file path";
+ if (!p.empty ())
+ return p;
+ error (l) << "empty " << n;
}
catch (const invalid_path& e)
{
- fail (l) << "invalid " << n << " redirect file path '" << e.path
- << "'";
+ error (l) << "invalid " << n << " '" << e.path << "'";
}
+ throw failed ();
+ };
+
+ auto add_file =
+ [&app, &parse_path] (redirect& r, string n, string&& w)
+ {
+ n += " redirect file path";
+ r.file.path = parse_path (n.c_str (), move (w));
r.file.append = app;
};
@@ -657,17 +665,7 @@ namespace build2
case pending::none: c.arguments.push_back (move (w)); break;
case pending::program:
{
- try
- {
- c.program = path (move (w));
-
- if (c.program.empty ())
- fail (l) << "empty program path";
- }
- catch (const invalid_path& e)
- {
- fail (l) << "invalid program path '" << e.path << "'";
- }
+ c.program = parse_path ("program path", move (w));
break;
}
@@ -685,6 +683,12 @@ namespace build2
case pending::in_file: add_file (c.in, "stdin", move (w)); break;
case pending::out_file: add_file (c.out, "stdout", move (w)); break;
case pending::err_file: add_file (c.err, "stderr", move (w)); break;
+
+ case pending::clean:
+ {
+ c.cleanups.push_back (parse_path ("cleanup path", move (w)));
+ break;
+ }
}
p = pending::none;
@@ -713,6 +717,7 @@ namespace build2
case pending::err_string: what = "stderr here-string"; break;
case pending::err_document: what = "stderr here-document end"; break;
case pending::err_file: what = "stderr file"; break;
+ case pending::clean: what = "cleanup path"; break;
}
if (what != nullptr)
@@ -902,6 +907,8 @@ namespace build2
case type::in_file:
case type::out_file:
case type::out_file_app:
+
+ case type::clean:
{
if (pre_parse_)
{
@@ -966,12 +973,21 @@ namespace build2
case type::in_file:
case type::out_file:
case type::out_file_app:
+ {
+ parse_redirect (t, l);
+ break;
+ }
- parse_redirect (t, l);
- next (t, tt);
- break;
+ case type::clean:
+ {
+ p = pending::clean;
+ break;
+ }
+
+ default: assert (false); break;
}
+ next (t, tt);
break;
}
default:
@@ -1115,6 +1131,12 @@ namespace build2
break;
}
+ case type::clean:
+ {
+ p = pending::clean;
+ break;
+ }
+
case type::in_doc:
case type::out_doc:
diff --git a/build2/test/script/script b/build2/test/script/script
index a21f0c6..a841d6c 100644
--- a/build2/test/script/script
+++ b/build2/test/script/script
@@ -121,6 +121,8 @@ namespace build2
redirect out;
redirect err;
+ paths cleanups;
+
command_exit exit {exit_comparison::eq, 0};
};
diff --git a/build2/test/script/script.cxx b/build2/test/script/script.cxx
index 8de023f..bf53595 100644
--- a/build2/test/script/script.cxx
+++ b/build2/test/script/script.cxx
@@ -4,6 +4,8 @@
#include <build2/test/script/script>
+#include <sstream>
+
#include <build2/target>
using namespace std;
@@ -32,7 +34,19 @@ namespace build2
void
to_stream (ostream& o, const command& c, command_to_stream m)
{
- auto print_redirect = [&o] (const redirect& r, const char* prefix)
+ auto print_path = [&o] (const path& p)
+ {
+ using build2::operator<<;
+
+ ostringstream s;
+ stream_verb (s, stream_verb (o));
+ s << p;
+
+ to_stream_q (o, s.str ());
+ };
+
+ auto print_redirect =
+ [&o, print_path] (const redirect& r, const char* prefix)
{
o << ' ' << prefix;
@@ -72,11 +86,10 @@ namespace build2
}
case redirect_type::file:
{
- using build2::operator<<;
-
// Add '>>' or '<<' (and so make it '<<<' or '>>>').
//
- o << d << d << (r.file.append ? "&" : "") << r.file.path;
+ o << d << d << (r.file.append ? "&" : "");
+ print_path (r.file.path);
break;
}
}
@@ -109,6 +122,12 @@ namespace build2
if (c.out.type != redirect_type::none) print_redirect (c.out, ">");
if (c.err.type != redirect_type::none) print_redirect (c.err, "2>");
+ for (const auto& p: c.cleanups)
+ {
+ o << " &";
+ print_path (p);
+ }
+
if (c.exit.comparison != exit_comparison::eq || c.exit.status != 0)
{
switch (c.exit.comparison)
diff --git a/unit-tests/test/script/lexer/command-line.test b/unit-tests/test/script/lexer/command-line.test
index 4a71d46..bc791dc 100644
--- a/unit-tests/test/script/lexer/command-line.test
+++ b/unit-tests/test/script/lexer/command-line.test
@@ -117,3 +117,13 @@ $* <:"1>>>&a b" >>EOO # out-file-app-redirect
>>>&
'a b'
EOO
+
+$* <:"&file" >>EOO # file-cleanup
+&
+'file'
+EOO
+
+$* <:"&dir/" >>EOO # dir-cleanup
+&
+'dir/'
+EOO
diff --git a/unit-tests/test/script/lexer/script-line.test b/unit-tests/test/script/lexer/script-line.test
index 36d440c..6c5038a 100644
--- a/unit-tests/test/script/lexer/script-line.test
+++ b/unit-tests/test/script/lexer/script-line.test
@@ -92,3 +92,12 @@ $* <"cmd <<<in >>>out 2>>>&err" >>EOO # file-redirect
'err'
<newline>
EOO
+
+$* <"cmd &file &dir/" >>EOO # cleanup
+'cmd'
+&
+'file'
+&
+'dir/'
+<newline>
+EOO
diff --git a/unit-tests/test/script/parser/buildfile b/unit-tests/test/script/parser/buildfile
index b053971..e64159e 100644
--- a/unit-tests/test/script/parser/buildfile
+++ b/unit-tests/test/script/parser/buildfile
@@ -11,7 +11,7 @@ filesystem config/{utility init operation} dump types-parsers \
test/{target script/{token lexer parser script}}
exe{driver}: cxx{driver} ../../../../build2/cxx{$src} $libs \
-test{pre-parse expansion redirect here-document command-re-parse scope \
- setup-teardown}
+test{cleanup command-re-parse expansion here-document pre-parse redirect \
+ scope setup-teardown}
include ../../../../build2/
diff --git a/unit-tests/test/script/parser/cleanup.test b/unit-tests/test/script/parser/cleanup.test
new file mode 100644
index 0000000..7fe746d
--- /dev/null
+++ b/unit-tests/test/script/parser/cleanup.test
@@ -0,0 +1,35 @@
+$* <<EOI >>EOO # file-dir
+cmd &file &dir/
+EOI
+cmd &file &dir/
+EOO
+
+$* <<EOI >>EOO # quote-file-dir
+cmd &"f ile" &"d ir/"
+EOI
+cmd &"f ile" &"d ir/"
+EOO
+
+$* <<EOI >>EOO # dup-file
+cmd &file &file
+EOI
+cmd &file &file
+EOO
+
+$* <<EOI 2>>EOE != 0 # file-fail1
+cmd & >file
+EOI
+testscript:1:7: error: missing cleanup path
+EOE
+
+$* <<EOI 2>>EOE != 0 # file-fail2
+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