aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2021-12-06 08:33:15 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2021-12-06 08:33:15 +0200
commit2006284bfbda3416eb8348078fd98fa518d25c47 (patch)
tree960d8495e1d4a011348ab719fa486af49a50f912
parentdcd8ccd86ca97de5293efc50f98d7072ee359e4c (diff)
Redo make_parser interface to return path, handle invalid_path exception
-rw-r--r--libbuild2/adhoc-rule-buildscript.cxx4
-rw-r--r--libbuild2/build/script/parser.cxx6
-rw-r--r--libbuild2/make-parser.cxx13
-rw-r--r--libbuild2/make-parser.hxx22
-rw-r--r--libbuild2/make-parser.test.cxx2
5 files changed, 27 insertions, 20 deletions
diff --git a/libbuild2/adhoc-rule-buildscript.cxx b/libbuild2/adhoc-rule-buildscript.cxx
index 3f3d59e..14df51a 100644
--- a/libbuild2/adhoc-rule-buildscript.cxx
+++ b/libbuild2/adhoc-rule-buildscript.cxx
@@ -911,7 +911,7 @@ namespace build2
// Note that we don't really need a diag frame that prints the
// line being parsed since we are always parsing the file.
//
- pair<make_type, string> r (
+ pair<make_type, path> r (
make.next (l, pos, il, false /* strict */));
if (r.second.empty ())
@@ -922,7 +922,7 @@ namespace build2
if (r.first == make_type::target)
continue;
- path f (move (r.second));
+ path& f (r.second);
if (f.relative ())
{
diff --git a/libbuild2/build/script/parser.cxx b/libbuild2/build/script/parser.cxx
index 2210cc8..042eabb 100644
--- a/libbuild2/build/script/parser.cxx
+++ b/libbuild2/build/script/parser.cxx
@@ -1866,7 +1866,7 @@ namespace build2
size_t pos (0);
do
{
- pair<make_type, string> r;
+ pair<make_type, path> r;
{
auto df = make_diag_frame (
[this, &l] (const diag_record& dr)
@@ -1908,9 +1908,7 @@ namespace build2
if (r.first == make_type::target)
continue;
- if (optional<bool> u = add (path (move (r.second)),
- &skip,
- rmt))
+ if (optional<bool> u = add (move (r.second), &skip, rmt))
{
restart = *u;
diff --git a/libbuild2/make-parser.cxx b/libbuild2/make-parser.cxx
index d076a0a..cab81d0 100644
--- a/libbuild2/make-parser.cxx
+++ b/libbuild2/make-parser.cxx
@@ -11,7 +11,7 @@ namespace build2
next (const string& l,
size_t& p,
const location& ll,
- bool strict) -> pair<type, string>
+ bool strict) -> pair<type, path>
{
assert (state != end);
@@ -55,7 +55,16 @@ namespace build2
state = end; // Not a mere optimization: the caller will get next line.
}
- return pair<type, string> (t, move (r.first));
+ try
+ {
+ return pair<type, path> (t, path (move (r.first)));
+ }
+ catch (const invalid_path& e)
+ {
+ fail (ll) << "invalid make "
+ << (t == type::prereq ? "prerequisite" : "target")
+ << " path '" << e.path << "'" << endf;
+ }
}
pair<string, bool> make_parser::
diff --git a/libbuild2/make-parser.hxx b/libbuild2/make-parser.hxx
index fac2215..2ff7be2 100644
--- a/libbuild2/make-parser.hxx
+++ b/libbuild2/make-parser.hxx
@@ -24,26 +24,26 @@ namespace build2
// Parse next target/prerequisite on a line starting from the specified
// position. Update the position to point to the start of the following
- // target/prerequisite or l.size() if there is nothing left on this
- // line. May return an empty string for a valid if unlikely dependency
+ // target/prerequisite or line.size() if there is nothing left on this
+ // line. May return an empty path for a valid if unlikely dependency
// declarations (see below) or if passing leading blank lines (both of
// which should normally be just skipped). Issue diagnostics and throw
- // failed if the declaration is invalid.
+ // failed if the declaration or path is invalid.
//
// If strict is false, then allow unescaped `:` in prerequisites.
//
- // Note that the (p != l.size) should be in the do-while rather than in a
- // while loop. In other words, except for the leading blank lines, the
- // parser needs to see the blank line to correctly identify the end of the
- // declaration. See make-parser.test.cxx for a recommended usage.
+ // Note that the (pos != line.size) should be in the do-while rather than
+ // in a while loop. In other words, except for the leading blank lines,
+ // the parser needs to see the blank line to correctly identify the end of
+ // the declaration. See make-parser.test.cxx for a recommended usage.
//
// To parse more than one declaration, reset the state to begin after
// reaching end.
//
enum class type {target, prereq};
- pair<type, string>
- next (const string&, size_t&, const location&, bool strict);
+ pair<type, path>
+ next (const string& line, size_t& pos, const location&, bool strict);
// Lower-level stateless API.
//
@@ -52,7 +52,7 @@ namespace build2
// position. Return the target/prerequisite as well as an indication of
// whether the end of the dependency declaration was reached. Update the
// position to point to the start of the following target/prerequisite,
- // `:`, or l.size() if there is nothing left on this line.
+ // `:`, or line.size() if there is nothing left on this line.
//
// Note that some broken tools (notably MinGW GCC) do not escape `:`
// properly. To tolerate such cases the caller may specify that what's
@@ -78,7 +78,7 @@ namespace build2
// baz
//
static pair<string, bool>
- next (const string&, size_t&, optional<bool> prereq = nullopt);
+ next (const string& line, size_t& pos, optional<bool> prereq = nullopt);
};
}
diff --git a/libbuild2/make-parser.test.cxx b/libbuild2/make-parser.test.cxx
index 189407a..9f60bad 100644
--- a/libbuild2/make-parser.test.cxx
+++ b/libbuild2/make-parser.test.cxx
@@ -54,7 +54,7 @@ namespace build2
size_t pos (0);
do
{
- pair<make_type, string> r (make.next (l, pos, ll, strict));
+ pair<make_type, path> r (make.next (l, pos, ll, strict));
cout << (r.first == make_type::target ? 'T' : 'P');