diff options
Diffstat (limited to 'libbuild2/script/run.hxx')
-rw-r--r-- | libbuild2/script/run.hxx | 66 |
1 files changed, 62 insertions, 4 deletions
diff --git a/libbuild2/script/run.hxx b/libbuild2/script/run.hxx index 01b010c..5d46d21 100644 --- a/libbuild2/script/run.hxx +++ b/libbuild2/script/run.hxx @@ -38,22 +38,24 @@ namespace build2 // Location is the start position of this command line in the script. It // can be used in diagnostics. // - // Optionally, save the command output into the referenced variable. In - // this case assume that the expression contains a single pipline. + // Optionally, execute the specified function at the end of the pipe, + // either after the last command or instead of it. // void run (environment&, const command_expr&, const iteration_index*, size_t index, const location&, - string* output = nullptr); + const function<command_function>& = nullptr, + bool last_cmd = true); bool run_cond (environment&, const command_expr&, const iteration_index*, size_t index, const location&, - string* output = nullptr); + const function<command_function>& = nullptr, + bool last_cmd = true); // Perform the registered special file cleanups in the direct order and // then the regular cleanups in the reverse order. @@ -80,6 +82,62 @@ namespace build2 // string diag_path (const dir_name_view&); + + // Read out the stream content into a string, optionally splitting the + // input data at whitespaces or newlines in which case return one + // sub-string at a time (see the set builtin options for the splitting + // semantics). Throw io_error on the underlying OS error. + // + // If the execution deadline is specified, then turn the stream into the + // non-blocking mode. If the specified deadline is reached while reading + // the stream, then bail out for the successful deadline and fail + // otherwise. Note that in the former case the result will be incomplete, + // but we leave it to the caller to handle that. + // + // Note that on Windows we can only turn pipe file descriptors into the + // non-blocking mode. Thus, we have no choice but to read from descriptors + // of other types synchronously there. That implies that we can + // potentially block indefinitely reading a file and missing the deadline + // on Windows. Note though, that the user can normally rewrite the + // command, for example, `set foo <<<file` with `cat file | set foo` to + // avoid this problem. + // + class stream_reader + { + public: + stream_reader (auto_fd&&, + bool pipe, + bool whitespace, bool newline, bool exact, + const optional<deadline>&, + const command& deadline_cmd, + const location&); + + // Return nullopt if eos is reached. + // + optional<string> + next (); + + private: + ifdstream is_; + bool whitespace_; + bool newline_; + bool exact_; + optional<deadline> deadline_; + const command& deadline_cmd_; + const location& location_; + + bool empty_ = true; // Set to false after the first character is read. + }; + + // Read the stream content using the stream reader in the no-split exact + // mode. + // + string + stream_read (auto_fd&&, + bool pipe, + const optional<deadline>&, + const command& deadline_cmd, + const location&); } } |