aboutsummaryrefslogtreecommitdiff
path: root/build2/utility.hxx
diff options
context:
space:
mode:
Diffstat (limited to 'build2/utility.hxx')
-rw-r--r--build2/utility.hxx664
1 files changed, 0 insertions, 664 deletions
diff --git a/build2/utility.hxx b/build2/utility.hxx
deleted file mode 100644
index 0aa5537..0000000
--- a/build2/utility.hxx
+++ /dev/null
@@ -1,664 +0,0 @@
-// file : build2/utility.hxx -*- C++ -*-
-// copyright : Copyright (c) 2014-2019 Code Synthesis Ltd
-// license : MIT; see accompanying LICENSE file
-
-#ifndef BUILD2_UTILITY_HXX
-#define BUILD2_UTILITY_HXX
-
-#include <tuple> // make_tuple()
-#include <memory> // make_shared()
-#include <string> // to_string()
-#include <utility> // move(), forward(), declval(), make_pair(), swap()
-#include <cassert> // assert()
-#include <iterator> // make_move_iterator()
-#include <algorithm> // *
-#include <functional> // ref(), cref()
-
-#include <libbutl/ft/lang.hxx>
-
-#include <libbutl/utility.mxx> // combine_hash(), reverse_iterate(), etc
-
-#include <unordered_set>
-
-#include <build2/types.hxx>
-
-// "Fake" version values used during bootstrap.
-//
-#ifdef BUILD2_BOOTSTRAP
-# define BUILD2_VERSION 9999999999999990000ULL
-# define BUILD2_VERSION_STR "99999.99999.99999"
-# define BUILD2_VERSION_ID "99999.99999.99999"
-# define LIBBUTL_VERSION_STR "99999.99999.99999"
-# define LIBBUTL_VERSION_ID "99999.99999.99999"
-#else
-# include <build2/version.hxx>
-#endif
-
-namespace build2
-{
- using std::move;
- using std::swap;
- using std::forward;
- using std::declval;
-
- using std::ref;
- using std::cref;
-
- using std::make_pair;
- using std::make_tuple;
- using std::make_shared;
- using std::make_move_iterator;
- using std::to_string;
- using std::stoul;
- using std::stoull;
-
- // <libbutl/utility.mxx>
- //
- using butl::reverse_iterate;
- using butl::compare_c_string;
- using butl::compare_pointer_target;
- //using butl::hash_pointer_target;
- using butl::combine_hash;
- using butl::casecmp;
- using butl::case_compare_string;
- using butl::case_compare_c_string;
- using butl::lcase;
- using butl::alpha;
- using butl::alnum;
- using butl::digit;
-
- using butl::trim;
- using butl::next_word;
-
- using butl::make_guard;
- using butl::make_exception_guard;
-
- using butl::getenv;
- using butl::setenv;
- using butl::unsetenv;
-
- using butl::throw_generic_error;
- using butl::throw_system_error;
-
- using butl::eof;
-
- // Diagnostics state (verbosity level, etc; see diagnostics.hxx).
- //
- // Note on naming of values (here and in the global state below) that come
- // from the command line options: if a value is not meant to be used
- // directly, then it has the _option suffix and a function or another
- // variable as its public interface.
-
- // Initialize the diagnostics state. Should be called once early in main().
- // Default values are for unit tests.
- //
- void
- init_diag (uint16_t verbosity,
- optional<bool> progress = nullopt,
- bool no_lines = false,
- bool no_columns = false,
- bool stderr_term = false);
-
- extern uint16_t verb;
- const uint16_t verb_never = 7;
-
- extern optional<bool> diag_progress_option; // --[no-]progress
-
- extern bool diag_no_line; // --no-line
- extern bool diag_no_column; // --no-column
-
- extern bool stderr_term; // True if stderr is a terminal.
-
- // Global state (verbosity, home/work directories, etc).
-
- // Initialize the global state. Should be called once early in main().
- // Default values are for unit tests.
- //
- void
- init (const char* argv0,
- bool keep_going = false,
- bool dry_run = false,
- optional<bool> mtime_check = nullopt,
- optional<path> config_sub = nullopt,
- optional<path> config_guess = nullopt);
-
- // Build system driver process path (argv0.initial is argv[0]).
- //
- extern process_path argv0;
-
- // Build system driver version and check.
- //
- extern const standard_version build_version;
-
- extern bool dry_run_option; // --dry-run
- extern optional<bool> mtime_check_option; // --[no-]mtime-check
-
- extern optional<path> config_sub; // --config-sub
- extern optional<path> config_guess; // --config-guess
-
- class location;
-
- void
- check_build_version (const standard_version_constraint&, const location&);
-
- // Work/home directories (must be initialized in main()) and relative path
- // calculation.
- //
- extern dir_path work;
- extern dir_path home;
-
- // By default this points to work. Setting this to something else should
- // only be done in tightly controlled, non-concurrent situations (e.g.,
- // state dump). If it is empty, then relative() below returns the original
- // path.
- //
- extern const dir_path* relative_base;
-
- // If possible and beneficial, translate an absolute, normalized path into
- // relative to the relative_base directory, which is normally work. Note
- // that if the passed path is the same as relative_base, then this function
- // returns empty path.
- //
- template <typename K>
- basic_path<char, K>
- relative (const basic_path<char, K>&);
-
- class path_target;
-
- path
- relative (const path_target&);
-
- // In addition to calling relative(), this function also uses shorter
- // notations such as '~/'. For directories the result includes the trailing
- // slash. If the path is the same as base, returns "./" if current is true
- // and empty string otherwise.
- //
- string
- diag_relative (const path&, bool current = true);
-
- // Basic process utilities.
- //
- // The run*() functions with process_path assume that you are printing
- // the process command line yourself.
-
- // Search for a process executable. Issue diagnostics and throw failed in
- // case of an error.
- //
- process_path
- run_search (const char*& args0,
- bool path_only,
- const location& = location ());
-
- inline process_path
- run_search (const char*& args0, const location& l = location ())
- {
- return run_search (args0, false, l);
- }
-
- process_path
- run_search (const path&,
- bool init = false,
- const dir_path& fallback = dir_path (),
- bool path_only = false,
- const location& = location ());
-
- process_path
- try_run_search (const path&,
- bool init = false,
- const dir_path& fallback = dir_path (),
- bool path_only = false);
-
- // 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 (),
- const location& = location ());
-
- inline void
- run_finish (cstrings& args, process& pr, const location& l = location ())
- {
- run_finish (args.data (), pr, true, string (), l);
- }
-
- // Start a process with the specified arguments. If in is -1, then redirect
- // STDIN to a pipe (can also be -2 to redirect to /dev/null or equivalent).
- // 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 (uint16_t verbosity,
- const process_env&, // Implicit-constructible from process_path.
- const char* args[],
- int in,
- int out,
- bool error = true,
- const dir_path& cwd = dir_path (),
- const location& = location ());
-
- inline process
- run_start (const process_env& pe, // Implicit-constructible from process_path.
- const char* args[],
- int in,
- int out,
- bool error = true,
- const dir_path& cwd = dir_path (),
- const location& l = location ())
- {
- return run_start (verb_never, pe, args, in, out, error, cwd, l);
- }
-
- inline void
- run (const process_path& p,
- const char* args[],
- const dir_path& cwd = dir_path ())
- {
- process pr (run_start (p, args, 0 /* stdin */, 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 (uint16_t verbosity,
- const char* args[],
- int in,
- int out,
- bool error = true,
- const dir_path& cwd = dir_path (),
- const location& l = location ())
- {
- process_path pp (run_search (args[0], l));
- return run_start (verbosity, pp, args, in, out, error, cwd, l);
- }
-
- inline process
- run_start (uint16_t verbosity,
- cstrings& args,
- int in,
- int out,
- bool error = true,
- const dir_path& cwd = dir_path (),
- const location& l = location ())
- {
- return run_start (verbosity, args.data (), in, out, error, cwd, l);
- }
-
- inline void
- run (uint16_t verbosity,
- const char* args[],
- const dir_path& cwd = dir_path ())
- {
- process pr (run_start (verbosity,
- args,
- 0 /* stdin */,
- 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
- // with T::empty()) which is then returned to the caller.
- //
- // The predicate can move the value out of the passed string but, if error
- // is false, only in case of a "content match" (so that any diagnostics
- // lines are left intact). The function signature should be:
- //
- // T (string& line, bool last)
- //
- // If ignore_exit is true, then the program's exit status is ignored (if it
- // is false and the program exits with the non-zero status, then an empty T
- // instance is returned).
- //
- // If checksum is not NULL, then feed it the content of each trimmed line
- // (including those that come after the callback returns non-empty object).
- //
- template <typename T, typename F>
- T
- run (uint16_t verbosity,
- const process_env&, // Implicit-constructible from process_path.
- const char* args[],
- F&&,
- bool error = true,
- bool ignore_exit = false,
- sha256* checksum = nullptr);
-
- template <typename T, typename F>
- inline T
- run (const process_env& pe, // Implicit-constructible from process_path.
- const char* args[],
- F&& f,
- bool error = true,
- bool ignore_exit = false,
- sha256* checksum = nullptr)
- {
- return run<T> (
- verb_never, pe, args, forward<F> (f), error, ignore_exit, checksum);
- }
-
- template <typename T, typename F>
- inline T
- run (uint16_t verbosity,
- const char* args[],
- F&& f,
- bool error = true,
- bool ignore_exit = false,
- sha256* checksum = nullptr)
- {
- process_path pp (run_search (args[0]));
- return run<T> (
- verbosity, pp, args, forward<F> (f), error, ignore_exit, checksum);
- }
-
- // run <prog>
- //
- template <typename T, typename F>
- inline T
- run (uint16_t verbosity,
- 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> (
- verbosity, args, forward<F> (f), error, ignore_exit, checksum);
- }
-
- template <typename T, typename F>
- inline T
- run (uint16_t verbosity,
- const process_env& pe, // Implicit-constructible from process_path.
- F&& f,
- bool error = true,
- bool ignore_exit = false,
- sha256* checksum = nullptr)
- {
- const char* args[] = {pe.path->recall_string (), nullptr};
- return run<T> (
- verbosity, pe, args, forward<F> (f), error, ignore_exit, checksum);
- }
-
- // run <prog> <arg>
- //
- template <typename T, typename F>
- inline T
- run (uint16_t verbosity,
- const path& prog,
- const char* arg,
- F&& f,
- bool error = true,
- bool ignore_exit = false,
- sha256* checksum = nullptr)
- {
- const char* args[] = {prog.string ().c_str (), arg, nullptr};
- return run<T> (
- verbosity, args, forward<F> (f), error, ignore_exit, checksum);
- }
-
- template <typename T, typename F>
- inline T
- run (uint16_t verbosity,
- const process_env& pe, // Implicit-constructible from process_path.
- const char* arg,
- F&& f,
- bool error = true,
- bool ignore_exit = false,
- sha256* checksum = nullptr)
- {
- const char* args[] = {pe.path->recall_string (), arg, nullptr};
- return run<T> (
- verbosity, pe, args, forward<F> (f), error, ignore_exit, checksum);
- }
-
- // Empty/nullopt string, path, and project name.
- //
- extern const string empty_string;
- extern const path empty_path;
- extern const dir_path empty_dir_path;
- extern const project_name empty_project_name;
-
- extern const optional<string> nullopt_string;
- extern const optional<path> nullopt_path;
- extern const optional<dir_path> nullopt_dir_path;
- extern const optional<project_name> nullopt_project_name;
-
- // Hash a path potentially without the specific directory prefix.
- //
- // If prefix is not empty and is a super-path of the path to hash, then only
- // hash the suffix. Note that both paths are assumed to be normalized.
- //
- // This functionality is normally used to strip out_root from target paths
- // being hashed in order to avoid updates in case out_root was moved. Note
- // that this should only be done if the result of the update does not
- // include the out_root path in any form (as could be the case, for example,
- // for debug information, __FILE__ macro expansion, rpath, etc).
- //
- void
- hash_path (sha256&, const path&, const dir_path& prefix = dir_path ());
-
- // Append all the values from a variable to the C-string list. T is either
- // target or scope. The variable is expected to be of type strings.
- //
- // If excl is not NULL, then filter this option out (note: case sensitive).
- //
- struct variable;
-
- template <typename T>
- void
- append_options (cstrings&, T&, const variable&, const char* excl = nullptr);
-
- template <typename T>
- void
- append_options (cstrings&, T&, const char*, const char* excl = nullptr);
-
- template <typename T>
- void
- append_options (strings&, T&, const variable&, const char* excl = nullptr);
-
- template <typename T>
- void
- append_options (strings&, T&, const char*, const char* excl = nullptr);
-
- template <typename T>
- void
- hash_options (sha256&, T&, const variable&);
-
- template <typename T>
- void
- hash_options (sha256&, T&, const char*);
-
- // As above but from the strings value directly.
- //
- class value;
- struct lookup;
-
- void
- append_options (cstrings&, const lookup&, const char* excl = nullptr);
-
- void
- append_options (strings&, const lookup&, const char* excl = nullptr);
-
- void
- hash_options (sha256&, const lookup&);
-
- void
- append_options (cstrings&, const strings&, const char* excl = nullptr);
-
- void
- append_options (strings&, const strings&, const char* excl = nullptr);
-
- void
- hash_options (sha256&, const strings&);
-
- void
- append_options (cstrings&,
- const strings&, size_t,
- const char* excl = nullptr);
-
- void
- append_options (strings&,
- const strings&, size_t,
- const char* excl = nullptr);
-
- void
- hash_options (sha256&, const strings&, size_t);
-
- // As above but append/hash option values for the specified option (e.g.,
- // -I, -L).
- //
- template <typename I, typename F>
- void
- append_option_values (cstrings&,
- const char* opt,
- I begin, I end,
- F&& get = [] (const string& s) {return s.c_str ();});
-
- template <typename I, typename F>
- void
- hash_option_values (sha256&,
- const char* opt,
- I begin, I end,
- F&& get = [] (const string& s) {return s;});
-
- // Check if a specified option is present in the variable or value. T is
- // either target or scope.
- //
- template <typename T>
- bool
- find_option (const char* option,
- T&,
- const variable&,
- bool ignore_case = false);
-
- template <typename T>
- bool
- find_option (const char* option,
- T&,
- const char* variable,
- bool ignore_case = false);
-
- bool
- find_option (const char* option, const lookup&, bool ignore_case = false);
-
- bool
- find_option (const char* option, const strings&, bool ignore_case = false);
-
- bool
- find_option (const char* option, const cstrings&, bool ignore_case = false);
-
- // As above but look for several options returning true if any is present.
- //
- template <typename T>
- bool
- find_options (initializer_list<const char*>,
- T&,
- const variable&,
- bool = false);
-
- template <typename T>
- bool
- find_options (initializer_list<const char*>, T&, const char*, bool = false);
-
- bool
- find_options (initializer_list<const char*>, const lookup&, bool = false);
-
- bool
- find_options (initializer_list<const char*>, const strings&, bool = false);
-
- bool
- find_options (initializer_list<const char*>, const cstrings&, bool = false);
-
- // As above but look for an option that has the specified prefix. Return the
- // pointer to option or NULL if not found (thus can be used as bool).
- // Search backward (which is normall consistent with how options override
- // each other).
- //
- template <typename T>
- const string*
- find_option_prefix (const char* prefix, T&, const variable&, bool = false);
-
- template <typename T>
- const string*
- find_option_prefix (const char* prefix, T&, const char*, bool = false);
-
- const string*
- find_option_prefix (const char* prefix, const lookup&, bool = false);
-
- const string*
- find_option_prefix (const char* prefix, const strings&, bool = false);
-
- const char*
- find_option_prefix (const char* prefix, const cstrings&, bool = false);
-
- // As above but look for several option prefixes.
- //
- template <typename T>
- const string*
- find_option_prefixes (initializer_list<const char*>,
- T&,
- const variable&,
- bool = false);
-
- template <typename T>
- const string*
- find_option_prefixes (initializer_list<const char*>,
- T&,
- const char*,
- bool = false);
-
- const string*
- find_option_prefixes (initializer_list<const char*>,
- const lookup&, bool = false);
-
- const string*
- find_option_prefixes (initializer_list<const char*>,
- const strings&,
- bool = false);
-
- const char*
- find_option_prefixes (initializer_list<const char*>,
- const cstrings&,
- bool = false);
-
- // Apply the specified substitution (stem) to a '*'-pattern. If pattern is
- // NULL or empty, then return the stem itself. Assume the pattern is valid,
- // i.e., contains a single '*' character.
- //
- string
- apply_pattern (const char* stem, const string* pattern);
-}
-
-#include <build2/utility.ixx>
-#include <build2/utility.txx>
-
-#endif // BUILD2_UTILITY_HXX