diff options
Diffstat (limited to 'libbuild2')
-rw-r--r-- | libbuild2/build/script/parser.cxx | 2 | ||||
-rw-r--r-- | libbuild2/build/script/runner.cxx | 8 | ||||
-rw-r--r-- | libbuild2/build/script/script.cxx | 6 | ||||
-rw-r--r-- | libbuild2/build/script/script.hxx | 5 | ||||
-rw-r--r-- | libbuild2/script/run.cxx | 51 | ||||
-rw-r--r-- | libbuild2/script/run.hxx | 8 | ||||
-rw-r--r-- | libbuild2/script/script.hxx | 5 | ||||
-rw-r--r-- | libbuild2/test/script/runner.cxx | 6 | ||||
-rw-r--r-- | libbuild2/test/script/script.cxx | 6 | ||||
-rw-r--r-- | libbuild2/test/script/script.hxx | 5 |
10 files changed, 74 insertions, 28 deletions
diff --git a/libbuild2/build/script/parser.cxx b/libbuild2/build/script/parser.cxx index c362776..95b835e 100644 --- a/libbuild2/build/script/parser.cxx +++ b/libbuild2/build/script/parser.cxx @@ -2826,7 +2826,7 @@ namespace build2 cmd, nullptr /* iteration_index */, li, ll, - cf, false /* last_cmd */); + cf); iss.exceptions (istream::badbit); } diff --git a/libbuild2/build/script/runner.cxx b/libbuild2/build/script/runner.cxx index 5d9764b..fc0fc05 100644 --- a/libbuild2/build/script/runner.cxx +++ b/libbuild2/build/script/runner.cxx @@ -143,7 +143,13 @@ namespace build2 (cf != nullptr && p.recall.string () == "for")); }) != expr.end ()) - build2::script::run (env, expr, ii, li, ll, cf); + { + build2::script::run (env, + expr, + ii, li, + ll, + cf, (cf != nullptr) /* replace_last_cmd */); + } else if (verb >= 2) text << expr; } diff --git a/libbuild2/build/script/script.cxx b/libbuild2/build/script/script.cxx index 0d96cc3..fba38a8 100644 --- a/libbuild2/build/script/script.cxx +++ b/libbuild2/build/script/script.cxx @@ -235,6 +235,12 @@ namespace build2 } } + void environment:: + sleep (const duration& d) + { + context.sched->sleep (d); + } + lookup environment:: lookup (const variable& var) const { diff --git a/libbuild2/build/script/script.hxx b/libbuild2/build/script/script.hxx index 08f1bf4..19f6d0b 100644 --- a/libbuild2/build/script/script.hxx +++ b/libbuild2/build/script/script.hxx @@ -189,6 +189,11 @@ namespace build2 virtual void create_temp_dir () override; + // Call the scheduler's sleep() function. + // + virtual void + sleep (const duration&) override; + // Variables. // public: diff --git a/libbuild2/script/run.cxx b/libbuild2/script/run.cxx index a0c76de..e669b29 100644 --- a/libbuild2/script/run.cxx +++ b/libbuild2/script/run.cxx @@ -1711,7 +1711,7 @@ namespace build2 const iteration_index* ii, size_t li, size_t ci, const location& ll, bool diag, - const function<command_function>& cf, bool last_cmd, + const function<command_function>& cf, bool replace_last_cmd, optional<deadline> dl = nullopt, pipe_command* prev_cmd = nullptr) { @@ -1723,7 +1723,7 @@ namespace build2 { if (cf != nullptr) { - assert (!last_cmd); // Otherwise we wouldn't be here. + assert (!replace_last_cmd); // Otherwise we wouldn't be here. // The pipeline can't be empty. // @@ -1798,8 +1798,9 @@ namespace build2 command_pipe::const_iterator nc (bc + 1); bool last (nc == ec); - // Make sure that stdout is not redirected if meant to be read (last_cmd - // is false) or cannot not be produced (last_cmd is true). + // Make sure that stdout is not redirected if meant to be read + // (replace_last_cmd is false) or cannot not be produced + // (replace_last_cmd is true). // if (last && c.out && cf != nullptr) fail (ll) << "stdout cannot be redirected"; @@ -1833,7 +1834,7 @@ namespace build2 // const redirect& in ((c.in ? *c.in : env.in).effective ()); - const redirect* out (!last || (cf != nullptr && !last_cmd) + const redirect* out (!last || (cf != nullptr && !replace_last_cmd) ? nullptr // stdout is piped. : &(c.out ? *c.out : env.out).effective ()); @@ -1842,8 +1843,8 @@ namespace build2 // If the output redirect is `none` (default for testscript) or `null` // and this is a builtin which is known not to write to stdout, then // redirect its stdout to stderr, unless stderr itself is redirected to - // stdout. This way we give up the expensive fdopen() call in favor of - // the cheap fddup() call. + // stdout. This way we replace the expensive fdopen(/dev/null) call with + // the cheap fddup(...) call. // // Note that we ignore the pseudo builtins since they are handled prior // to opening any file descriptors for stdout. @@ -1940,7 +1941,7 @@ namespace build2 if (c.out) fail (ll) << program << " builtin stdout cannot be redirected"; - if (cf != nullptr && !last_cmd) + if (cf != nullptr && !replace_last_cmd) fail (ll) << program << " builtin stdout cannot be read"; if (c.err) @@ -2181,7 +2182,7 @@ namespace build2 if (c.out) fail (ll) << "set builtin stdout cannot be redirected"; - if (cf != nullptr && !last_cmd) + if (cf != nullptr && !replace_last_cmd) fail (ll) << "set builtin stdout cannot be read"; if (c.err) @@ -2200,7 +2201,7 @@ namespace build2 // If this is the last command in the pipe and the command function is // specified for it, then call it. // - if (last && cf != nullptr && last_cmd) + if (last && cf != nullptr && replace_last_cmd) { // Must be enforced by the caller. // @@ -2389,7 +2390,7 @@ namespace build2 // Otherwise we wouldn't be here. // - assert (!last || (cf != nullptr && !last_cmd)); + assert (!last || (cf != nullptr && !replace_last_cmd)); ofd = open_pipe (); } @@ -3082,7 +3083,7 @@ namespace build2 // If/when required we could probably support the precise sleep // mode (e.g., via an option). // - env.context.sched->sleep (t); + env.sleep (t); } }; @@ -3118,7 +3119,7 @@ namespace build2 nc, ec, move (ofd.in), ii, li, ci + 1, ll, diag, - cf, last_cmd, + cf, replace_last_cmd, dl, &pc); @@ -3243,7 +3244,7 @@ namespace build2 nc, ec, move (ofd.in), ii, li, ci + 1, ll, diag, - cf, last_cmd, + cf, replace_last_cmd, dl, &pc); @@ -3296,7 +3297,7 @@ namespace build2 const iteration_index* ii, size_t li, const location& ll, bool diag, - const function<command_function>& cf, bool last_cmd) + const function<command_function>& cf, bool replace_last_cmd) { // Commands are numbered sequentially throughout the expression // starting with 1. Number 0 means the command is a single one. @@ -3341,7 +3342,7 @@ namespace build2 p.begin (), p.end (), auto_fd (), ii, li, ci, ll, print, - cf, last_cmd); + cf, replace_last_cmd); } ci += p.size (); @@ -3356,8 +3357,13 @@ namespace build2 const iteration_index* ii, size_t li, const location& ll, const function<command_function>& cf, - bool last_cmd) + bool replace_last_cmd) { + // If the last command in the pipeline is ought to be replaced, then the + // replacement function must be specified. + // + assert (!replace_last_cmd || cf != nullptr); + // Note that we don't print the expression at any verbosity level // assuming that the caller does this, potentially providing some // additional information (command type, etc). @@ -3366,7 +3372,7 @@ namespace build2 expr, ii, li, ll, true /* diag */, - cf, last_cmd)) + cf, replace_last_cmd)) throw failed (); // Assume diagnostics is already printed. } @@ -3375,15 +3381,20 @@ namespace build2 const command_expr& expr, const iteration_index* ii, size_t li, const location& ll, - const function<command_function>& cf, bool last_cmd) + const function<command_function>& cf, bool replace_last_cmd) { + // If the last command in the pipeline is ought to be replaced, then the + // replacement function must be specified. + // + assert (!replace_last_cmd || cf != nullptr); + // Note that we don't print the expression here (see above). // return run_expr (env, expr, ii, li, ll, false /* diag */, - cf, last_cmd); + cf, replace_last_cmd); } void diff --git a/libbuild2/script/run.hxx b/libbuild2/script/run.hxx index 955c37e..f41a3d0 100644 --- a/libbuild2/script/run.hxx +++ b/libbuild2/script/run.hxx @@ -39,9 +39,7 @@ namespace build2 // can be used in diagnostics. // // Optionally, execute the specified function at the end of the pipe, - // either after the last command (last_cmd=false) or instead of it - // (last_cmd=true). Note that the last_cmd argument is only meaningful if - // the function is specified. + // potentially instead of the last command (replace_last_cmd). // void run (environment&, @@ -49,7 +47,7 @@ namespace build2 const iteration_index*, size_t index, const location&, const function<command_function>& = nullptr, - bool last_cmd = true); + bool replace_last_cmd = false); bool run_cond (environment&, @@ -57,7 +55,7 @@ namespace build2 const iteration_index*, size_t index, const location&, const function<command_function>& = nullptr, - bool last_cmd = true); + bool replace_last_cmd = false); // Perform the registered special file cleanups in the direct order and // then the regular cleanups in the reverse order. diff --git a/libbuild2/script/script.hxx b/libbuild2/script/script.hxx index f5bd69a..76c4010 100644 --- a/libbuild2/script/script.hxx +++ b/libbuild2/script/script.hxx @@ -588,6 +588,11 @@ namespace build2 virtual void create_temp_dir () = 0; + // Used as an implementation of the sleep builtin. + // + virtual void + sleep (const duration&) = 0; + public: virtual ~environment () = default; diff --git a/libbuild2/test/script/runner.cxx b/libbuild2/test/script/runner.cxx index 98d6868..54009f6 100644 --- a/libbuild2/test/script/runner.cxx +++ b/libbuild2/test/script/runner.cxx @@ -182,7 +182,11 @@ namespace build2 }); ++sp.exec_level; - build2::script::run (sp, expr, ii, li, ll, cf); + build2::script::run (sp, + expr, + ii, li, + ll, + cf, (cf != nullptr) /* replace_last_cmd */); --sp.exec_level; } diff --git a/libbuild2/test/script/script.cxx b/libbuild2/test/script/script.cxx index 7862120..176daf3 100644 --- a/libbuild2/test/script/script.cxx +++ b/libbuild2/test/script/script.cxx @@ -181,6 +181,12 @@ namespace build2 : exported_vars; } + void scope:: + sleep (const duration& d) + { + context.sched->sleep (d); + } + // script_base // script_base:: diff --git a/libbuild2/test/script/script.hxx b/libbuild2/test/script/script.hxx index 9409b01..d1e0f53 100644 --- a/libbuild2/test/script/script.hxx +++ b/libbuild2/test/script/script.hxx @@ -140,6 +140,11 @@ namespace build2 virtual void create_temp_dir () override {assert (false);}; + // Call the scheduler's sleep() function. + // + virtual void + sleep (const duration&) override; + // Return true if this is a test program path. // // Note that currently the test program is only specified via the test |