From 2006284bfbda3416eb8348078fd98fa518d25c47 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Mon, 6 Dec 2021 08:33:15 +0200 Subject: Redo make_parser interface to return path, handle invalid_path exception --- libbuild2/adhoc-rule-buildscript.cxx | 4 ++-- libbuild2/build/script/parser.cxx | 6 ++---- libbuild2/make-parser.cxx | 13 +++++++++++-- libbuild2/make-parser.hxx | 22 +++++++++++----------- libbuild2/make-parser.test.cxx | 2 +- 5 files changed, 27 insertions(+), 20 deletions(-) (limited to 'libbuild2') 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 r ( + pair 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 r; + pair 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 u = add (path (move (r.second)), - &skip, - rmt)) + if (optional 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 + bool strict) -> pair { assert (state != end); @@ -55,7 +55,16 @@ namespace build2 state = end; // Not a mere optimization: the caller will get next line. } - return pair (t, move (r.first)); + try + { + return pair (t, path (move (r.first))); + } + catch (const invalid_path& e) + { + fail (ll) << "invalid make " + << (t == type::prereq ? "prerequisite" : "target") + << " path '" << e.path << "'" << endf; + } } pair 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 - next (const string&, size_t&, const location&, bool strict); + pair + 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 - next (const string&, size_t&, optional prereq = nullopt); + next (const string& line, size_t& pos, optional 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 r (make.next (l, pos, ll, strict)); + pair r (make.next (l, pos, ll, strict)); cout << (r.first == make_type::target ? 'T' : 'P'); -- cgit v1.1