diff options
Diffstat (limited to 'libbuild2/script/parser.cxx')
-rw-r--r-- | libbuild2/script/parser.cxx | 113 |
1 files changed, 67 insertions, 46 deletions
diff --git a/libbuild2/script/parser.cxx b/libbuild2/script/parser.cxx index bc433e4..88e2f06 100644 --- a/libbuild2/script/parser.cxx +++ b/libbuild2/script/parser.cxx @@ -1108,11 +1108,12 @@ namespace build2 hd.push_back ( here_doc { {rd}, - move (end), - (t.qtype == quote_type::unquoted || - t.qtype == quote_type::single), - move (mod), - r.intro, move (r.flags)}); + move (end), + (t.qtype == quote_type::unquoted || + t.qtype == quote_type::single), + move (mod), + r.intro, + move (r.flags)}); p = pending::none; mod.clear (); @@ -2449,7 +2450,7 @@ namespace build2 // Let's "wrap up" all the required data into the single object // to rely on the "small function object" optimization. // - struct + struct loop_data { lines::const_iterator i; lines::const_iterator e; @@ -2462,7 +2463,7 @@ namespace build2 variable_pool* var_pool; decltype (fcend)& fce; lines::const_iterator& fe; - } d {i, e, + } ld {i, e, exec_set, exec_cmd, exec_cond, exec_for, ii, li, var_pool, @@ -2470,13 +2471,12 @@ namespace build2 fe}; function<command_function> cf ( - [&d, this] + [&ld, this] (environment& env, const strings& args, auto_fd in, - bool pipe, + pipe_command* pipe, const optional<deadline>& dl, - const command& deadline_cmd, const location& ll) { namespace cli = build2::build::cli; @@ -2527,12 +2527,6 @@ namespace build2 << scan.next () << "'"; } - stream_reader sr ( - move (in), pipe, - !ops.newline (), ops.newline (), ops.exact (), - dl, deadline_cmd, - ll); - // Since the command pipe is parsed, we can stop // replaying. Note that we should do this before calling // exec_lines() for the loop body. Also note that we @@ -2540,39 +2534,66 @@ namespace build2 // replay_stop (); - size_t fli (++d.li); - iteration_index fi {1, d.ii}; + size_t fli (++ld.li); + iteration_index fi {1, ld.ii}; - for (optional<string> s; (s = sr.next ()); ) + // Let's "wrap up" all the required data into the single + // object to rely on the "small function object" + // optimization. + // + struct { - d.li = fli; - - // Don't move from the variable name since it is used on - // each iteration. - // - env.set_variable (vname, - names {name (move (*s))}, - attrs, - ll); - - // Find the construct end, if it is not found yet. - // - if (d.fe == d.e) - d.fe = d.fce (d.i, true, false); - - if (!exec_lines (d.i + 1, d.fe, - d.exec_set, - d.exec_cmd, - d.exec_cond, - d.exec_for, - &fi, d.li, - d.var_pool)) + loop_data& ld; + environment& env; + const string& vname; + const string& attrs; + const location& ll; + size_t fli; + iteration_index& fi; + + } d {ld, env, vname, attrs, ll, fli, fi}; + + function<void (string&&)> f ( + [&d, this] (string&& s) { - throw exit (true); - } - - fi.index++; - } + loop_data& ld (d.ld); + + ld.li = d.fli; + + // Don't move from the variable name since it is used + // on each iteration. + // + d.env.set_variable (d.vname, + names {name (move (s))}, + d.attrs, + d.ll); + + // Find the construct end, if it is not found yet. + // + if (ld.fe == ld.e) + ld.fe = ld.fce (ld.i, true, false); + + if (!exec_lines (ld.i + 1, ld.fe, + ld.exec_set, + ld.exec_cmd, + ld.exec_cond, + ld.exec_for, + &d.fi, ld.li, + ld.var_pool)) + { + throw exit (true); + } + + d.fi.index++; + }); + + read (move (in), + !ops.newline (), ops.newline (), ops.exact (), + f, + pipe, + dl, + ll, + "for"); } catch (const cli::exception& e) { |