aboutsummaryrefslogtreecommitdiff
path: root/build2/utility.hxx
diff options
context:
space:
mode:
Diffstat (limited to 'build2/utility.hxx')
-rw-r--r--build2/utility.hxx134
1 files changed, 111 insertions, 23 deletions
diff --git a/build2/utility.hxx b/build2/utility.hxx
index 77c46a8..db6460c 100644
--- a/build2/utility.hxx
+++ b/build2/utility.hxx
@@ -166,12 +166,16 @@ namespace build2
// Basic process utilities.
//
+ // The run*() functions with process_path assume that you are printing
+ // the process command line yourself.
- // Start a process with the specified arguments printing the command at
- // verbosity level 3 and higher. Redirect STDOUT to a pipe. If error is
- // false, then redirecting STDERR to STDOUT (this can be used to suppress
- // diagnostics from the child process). Issue diagnostics and throw failed
- // in case of an error.
+ extern uint16_t verb; // diagnostics.hxx
+
+ void
+ print_process (const char* const*, size_t); // diagnostics.hxx
+
+ // Search for a process executable. Issue diagnostics and throw failed in
+ // case of an error.
//
process_path
run_search (const char*& args0);
@@ -179,20 +183,88 @@ namespace build2
process_path
run_search (const path&, bool init, const dir_path& fallback = dir_path ());
+ // Wait for process termination. Issue diagnostics and throw failed in case
+ // of abnormal termination. If the process has terminated normally but with
+ // a non-zero exit status, then, if error is true, assume the diagnostics
+ // has already been issued and throw failed as well. Otherwise (error is
+ // false), return false. The last argument is used in cooperation with
+ // run_start() in case STDERR is redirected to STDOUT.
+ //
+ bool
+ run_finish (const char* args[],
+ process&,
+ bool error = true,
+ const string& = string ());
+
+ inline void
+ run_finish (cstrings& args, process& pr)
+ {
+ run_finish (args.data (), pr);
+ }
+
+ // Start a process with the specified arguments. If out is -1, redirect
+ // STDOUT to a pipe. If error is false, then redirecting STDERR to STDOUT
+ // (this can be used to suppress diagnostics from the child process). Issue
+ // diagnostics and throw failed in case of an error.
+ //
process
- run_start (const process_path&, const char* args[], bool error = true);
+ run_start (const process_path&,
+ const char* args[],
+ int out,
+ bool error = true,
+ const dir_path& cwd = dir_path ());
+
+ inline void
+ run (const process_path& p,
+ const char* args[],
+ const dir_path& cwd = dir_path ())
+ {
+ process pr (run_start (p, args, 1 /* stdout */, true, cwd));
+ run_finish (args, pr);
+ }
+ inline void
+ run (const process_path& p,
+ cstrings& args,
+ const dir_path& cwd = dir_path ())
+ {
+ run (p, args.data (), cwd);
+ }
+
+ // As above, but search for the process (including updating args[0]) and
+ // print the process commands line at the specified verbosity level.
+ //
inline process
- run_start (const char* args[], bool error = true)
+ run_start (uint16_t verbosity,
+ const char* args[],
+ int out,
+ bool error = true,
+ const dir_path& cwd = dir_path ())
{
- return run_start (run_search (args[0]), args, error);
+ process_path pp (run_search (args[0]));
+
+ if (verb >= verbosity)
+ print_process (args, 0);
+
+ return run_start (pp, args, out, error, cwd);
}
- bool
- run_finish (const char* args[],
- process&,
- bool error = true,
- const string& = string ());
+ inline void
+ run (uint16_t verbosity,
+ const char* args[],
+ const dir_path& cwd = dir_path ())
+ {
+ process pr (run_start (verbosity, args, 1 /* stdout */, true, cwd));
+ run_finish (args, pr);
+ }
+
+ inline void
+ run (uint16_t verbosity,
+ cstrings& args,
+ const dir_path& cwd = dir_path ())
+ {
+ run (verbosity, args.data (), cwd);
+ }
// Start the process as above and then call the specified function on each
// trimmed line of the output until it returns a non-empty object T (tested
@@ -220,40 +292,50 @@ namespace build2
template <typename T, typename F>
inline T
- run (const char* args[],
+ run (uint16_t verbosity,
+ const char* args[],
F&& f,
bool error = true,
bool ignore_exit = false,
sha256* checksum = nullptr)
{
- return run<T> (
- run_search (
- args[0]), args, forward<F> (f), error, ignore_exit, checksum);
+ process_path pp (run_search (args[0]));
+
+ if (verb >= verbosity)
+ print_process (args, 0);
+
+ return run<T> (pp, args, forward<F> (f), error, ignore_exit, checksum);
}
// run <prog>
//
template <typename T, typename F>
inline T
- run (const path& prog,
+ run (uint16_t verb,
+ const path& prog,
F&& f,
bool error = true,
bool ignore_exit = false,
sha256* checksum = nullptr)
{
const char* args[] = {prog.string ().c_str (), nullptr};
- return run<T> (args, forward<F> (f), error, ignore_exit, checksum);
+ return run<T> (verb, args, forward<F> (f), error, ignore_exit, checksum);
}
template <typename T, typename F>
inline T
- run (const process_path& pp,
+ run (uint16_t verbosity,
+ const process_path& pp,
F&& f,
bool error = true,
bool ignore_exit = false,
sha256* checksum = nullptr)
{
const char* args[] = {pp.recall_string (), nullptr};
+
+ if (verb >= verbosity)
+ print_process (args, 0);
+
return run<T> (pp, args, forward<F> (f), error, ignore_exit, checksum);
}
@@ -261,7 +343,8 @@ namespace build2
//
template <typename T, typename F>
inline T
- run (const path& prog,
+ run (uint16_t verb,
+ const path& prog,
const char* arg,
F&& f,
bool error = true,
@@ -269,12 +352,13 @@ namespace build2
sha256* checksum = nullptr)
{
const char* args[] = {prog.string ().c_str (), arg, nullptr};
- return run<T> (args, forward<F> (f), error, ignore_exit, checksum);
+ return run<T> (verb, args, forward<F> (f), error, ignore_exit, checksum);
}
template <typename T, typename F>
inline T
- run (const process_path& pp,
+ run (uint16_t verbosity,
+ const process_path& pp,
const char* arg,
F&& f,
bool error = true,
@@ -282,6 +366,10 @@ namespace build2
sha256* checksum = nullptr)
{
const char* args[] = {pp.recall_string (), arg, nullptr};
+
+ if (verb >= verbosity)
+ print_process (args, 0);
+
return run<T> (pp, args, forward<F> (f), error, ignore_exit, checksum);
}