aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2016-11-02 16:55:57 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2016-11-04 09:26:37 +0200
commit7e97d8a41f9d7b0fb82742cdd871a18804267c72 (patch)
treefa7a695b348cac0c881d1bbb0c0071fb77f34040
parentd7aeb79c65338320a690b404b613f0671a65e403 (diff)
Restructure testscript parser slightly
-rw-r--r--build2/test/rule.cxx20
-rw-r--r--build2/test/script/parser11
-rw-r--r--build2/test/script/parser.cxx31
-rw-r--r--build2/test/script/script12
-rw-r--r--unit-tests/test/script/parser/driver.cxx10
5 files changed, 54 insertions, 30 deletions
diff --git a/build2/test/rule.cxx b/build2/test/rule.cxx
index 12b052f..487856b 100644
--- a/build2/test/rule.cxx
+++ b/build2/test/rule.cxx
@@ -423,23 +423,11 @@ namespace build2
if (verb)
text << "test " << t << " with " << ts;
- const path& sp (ts.path ());
- assert (!sp.empty ()); // Should have been assigned by update.
+ script::parser p;
+ script::script s (p.pre_parse (ts, t, wd));
- try
- {
- script::script s (t, ts, wd);
- script::concurrent_runner r;
-
- ifdstream ifs (sp);
- script::parser p;
- p.pre_parse (ifs, sp, s);
- p.parse (sp, s, r);
- }
- catch (const io_error& e)
- {
- fail << "unable to read testscript " << sp << ": " << e.what ();
- }
+ script::concurrent_runner r;
+ p.parse (s, r);
};
for (target* pt: t.prerequisite_targets)
diff --git a/build2/test/script/parser b/build2/test/script/parser
index b5c77fe..cff1b39 100644
--- a/build2/test/script/parser
+++ b/build2/test/script/parser
@@ -28,13 +28,16 @@ namespace build2
public:
// Issue diagnostics and throw failed in case of an error.
//
- void
- pre_parse (istream&, const path& name, script&);
+ script
+ pre_parse (testscript&, target&, const dir_path& root_wd);
+
+ script
+ pre_parse (istream&, testscript&, target&, const dir_path& root_wd);
void
- parse (const path& name, script& s, runner& r)
+ parse (script& s, runner& r)
{
- parse (s, name, s, r);
+ parse (s, s.script_target.path (), s, r);
}
// Recursive descent parser.
diff --git a/build2/test/script/parser.cxx b/build2/test/script/parser.cxx
index 27d8888..6520458 100644
--- a/build2/test/script/parser.cxx
+++ b/build2/test/script/parser.cxx
@@ -17,10 +17,29 @@ namespace build2
{
using type = token_type;
- void parser::
- pre_parse (istream& is, const path& p, script& s)
+ script parser::
+ pre_parse (testscript& ts, target& tg, const dir_path& wd)
{
- path_ = &p;
+ const path& p (ts.path ());
+ assert (!p.empty ()); // Should have been assigned.
+
+ try
+ {
+ ifdstream ifs (p);
+ return pre_parse (ifs, ts, tg, wd);
+ }
+ catch (const io_error& e)
+ {
+ error << "unable to read testscript " << p << ": " << e.what ();
+ throw failed ();
+ }
+ }
+
+ script parser::
+ pre_parse (istream& is, testscript& ts, target& tg, const dir_path& wd)
+ {
+ script s (tg, ts, wd);
+ path_ = &*s.testscripts_.insert (ts.path ()).first;
pre_parse_ = true;
@@ -36,8 +55,8 @@ namespace build2
id_map_ = &idm;
scope_ = nullptr;
- // Start location of the implied script group is the beginning of the
- // file. End location -- end of the file.
+ // Start location of the implied script group is the beginning of
+ // the file. End location -- end of the file.
//
group_->start_loc_ = location (path_, 1, 1);
@@ -47,6 +66,8 @@ namespace build2
fail (t) << "stray " << t;
group_->end_loc_ = get_location (t);
+
+ return s;
}
void parser::
diff --git a/build2/test/script/script b/build2/test/script/script
index 5f6b861..aff5a59 100644
--- a/build2/test/script/script
+++ b/build2/test/script/script
@@ -5,6 +5,8 @@
#ifndef BUILD2_TEST_SCRIPT_SCRIPT
#define BUILD2_TEST_SCRIPT_SCRIPT
+#include <set>
+
#include <build2/types>
#include <build2/utility>
@@ -293,6 +295,11 @@ namespace build2
location start_loc_;
location end_loc_;
+
+ // Set of testscript files already included in this scope. Paths must
+ // be absolute and normalized.
+ //
+ std::set<path> testscripts_;
};
// group
@@ -364,6 +371,11 @@ namespace build2
testscript& script_target,
const dir_path& root_wd);
+ script (script&&) = default;
+ script (const script&) = delete;
+ script& operator= (script&&) = delete;
+ script& operator= (const script&) = delete;
+
public:
target& test_target; // Target we are testing.
testscript& script_target; // Target of the testscript file.
diff --git a/unit-tests/test/script/parser/driver.cxx b/unit-tests/test/script/parser/driver.cxx
index 20e1e6a..deb9994 100644
--- a/unit-tests/test/script/parser/driver.cxx
+++ b/unit-tests/test/script/parser/driver.cxx
@@ -164,12 +164,12 @@ namespace build2
// Parse and run.
//
- script s (tt, st, dir_path (work) /= "test-driver");
- print_runner r (scope, id);
-
parser p;
- p.pre_parse (cin, name, s);
- p.parse (name, s, r);
+ script s (
+ p.pre_parse (cin, st, tt, dir_path (work) /= "test-driver"));
+
+ print_runner r (scope, id);
+ p.parse (s, r);
}
catch (const failed&)
{