aboutsummaryrefslogtreecommitdiff
path: root/libbuild2/script
diff options
context:
space:
mode:
authorKaren Arutyunov <karen@codesynthesis.com>2020-06-03 16:38:23 +0300
committerKaren Arutyunov <karen@codesynthesis.com>2020-06-04 14:20:33 +0300
commitd280946474568925016359be742b59fd6c000c52 (patch)
tree5b48a599c33f442867dfa32690e141883af0322d /libbuild2/script
parentf50d0d58c8eb659e803282e19cf15398e3a8e373 (diff)
Properly handle diag directive in build script parser
Diffstat (limited to 'libbuild2/script')
-rw-r--r--libbuild2/script/parser.cxx53
-rw-r--r--libbuild2/script/parser.hxx5
2 files changed, 31 insertions, 27 deletions
diff --git a/libbuild2/script/parser.cxx b/libbuild2/script/parser.cxx
index 33dc273..fd9399d 100644
--- a/libbuild2/script/parser.cxx
+++ b/libbuild2/script/parser.cxx
@@ -97,7 +97,7 @@ namespace build2
}
optional<process_path> parser::
- parse_program (token& t, type& tt, names& ns)
+ parse_program (token& t, type& tt, bool, names& ns)
{
parse_names (t, tt,
ns,
@@ -153,8 +153,7 @@ namespace build2
// Handles empty regex properly.
//
if (mod.find ('/') != string::npos && re[0] == '/')
- fail (l) << "portable path modifier and '/' introducer in "
- << what;
+ fail (l) << "portable path modifier and '/' introducer in " << what;
};
// Pending positions where the next word should go.
@@ -162,7 +161,8 @@ namespace build2
enum class pending
{
none,
- program,
+ program_first,
+ program_next,
in_string,
in_document,
in_file,
@@ -180,7 +180,7 @@ namespace build2
err_file,
clean
};
- pending p (pending::program);
+ pending p (pending::program_first);
string mod; // Modifiers for pending in_* and out_* positions.
here_docs hd; // Expected here-documents.
@@ -291,7 +291,8 @@ namespace build2
switch (p)
{
case pending::none: c.arguments.push_back (move (w)); break;
- case pending::program:
+ case pending::program_first:
+ case pending::program_next:
c.program = process_path (nullptr /* initial */,
parse_path (move (w), "program path"),
path () /* effect */);
@@ -355,20 +356,21 @@ namespace build2
switch (p)
{
- case pending::none: break;
- case pending::program: what = "program"; break;
- case pending::in_string: what = "stdin here-string"; break;
- case pending::in_document: what = "stdin here-document end"; break;
- case pending::in_file: what = "stdin file"; break;
- case pending::out_merge: what = "stdout file descriptor"; break;
- case pending::out_string: what = "stdout here-string"; break;
- case pending::out_document: what = "stdout here-document end"; break;
- case pending::out_file: what = "stdout file"; break;
- case pending::err_merge: what = "stderr file descriptor"; break;
- 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;
+ case pending::none: break;
+ case pending::program_first:
+ case pending::program_next: what = "program"; break;
+ case pending::in_string: what = "stdin here-string"; break;
+ case pending::in_document: what = "stdin here-document end"; break;
+ case pending::in_file: what = "stdin file"; break;
+ case pending::out_merge: what = "stdout file descriptor"; break;
+ case pending::out_string: what = "stdout here-string"; break;
+ case pending::out_document: what = "stdout here-document end"; break;
+ case pending::out_file: what = "stdout file"; break;
+ case pending::err_merge: what = "stderr file descriptor"; break;
+ 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;
case pending::out_str_regex:
{
@@ -752,7 +754,7 @@ namespace build2
case type::pipe:
case type::log_or:
case type::log_and:
- p = pending::program;
+ p = pending::program_next;
break;
case type::in_doc:
@@ -886,7 +888,7 @@ namespace build2
expr.back ().pipe.push_back (move (c));
c = command ();
- p = pending::program;
+ p = pending::program_next;
if (tt != type::pipe)
{
@@ -1031,9 +1033,10 @@ namespace build2
//
reset_quoted (t);
- if (p == pending::program)
+ if (p == pending::program_first || p == pending::program_next)
{
- optional<process_path> pp (parse_program (t, tt, ns));
+ optional<process_path> pp (
+ parse_program (t, tt, p == pending::program_first, ns));
// During pre-parsing we are not interested in the
// parse_program() call result, so just discard the potentially
@@ -1195,7 +1198,7 @@ namespace build2
expr.back ().pipe.push_back (move (c));
c = command ();
- p = pending::program;
+ p = pending::program_next;
if (tt != type::pipe)
{
diff --git a/libbuild2/script/parser.hxx b/libbuild2/script/parser.hxx
index b15f632..bec6867 100644
--- a/libbuild2/script/parser.hxx
+++ b/libbuild2/script/parser.hxx
@@ -165,7 +165,8 @@ namespace build2
// Customization hooks.
//
protected:
- // Parse the command's leading name chunk.
+ // Parse the command's leading name chunk. The argument first is true if
+ // this is the first command in the line.
//
// During the execution phase try to parse and translate the leading
// names into the process path and return nullopt if choose not to do
@@ -188,7 +189,7 @@ namespace build2
// recognize and execute certain directives, or some such.
//
virtual optional<process_path>
- parse_program (token&, token_type&, names&);
+ parse_program (token&, token_type&, bool first, names&);
// Set lexer pointers for both the current and the base classes.
//