diff options
Diffstat (limited to 'build2/utility.cxx')
-rw-r--r-- | build2/utility.cxx | 517 |
1 files changed, 0 insertions, 517 deletions
diff --git a/build2/utility.cxx b/build2/utility.cxx deleted file mode 100644 index 9448c03..0000000 --- a/build2/utility.cxx +++ /dev/null @@ -1,517 +0,0 @@ -// file : build2/utility.cxx -*- C++ -*- -// copyright : Copyright (c) 2014-2019 Code Synthesis Ltd -// license : MIT; see accompanying LICENSE file - -#include <build2/utility.hxx> - -#include <time.h> // tzset() (POSIX), _tzset() (Windows) - -#include <cstring> // strlen(), str[n]cmp() -#include <iostream> // cerr - -#include <build2/target.hxx> -#include <build2/variable.hxx> -#include <build2/diagnostics.hxx> - -using namespace std; -using namespace butl; - -// -// <build2/types.hxx> -// -namespace build2 -{ - static const char* const run_phase_[] = {"load", "match", "execute"}; - - ostream& - operator<< (ostream& os, run_phase p) - { - return os << run_phase_[static_cast<uint8_t> (p)]; - } -} - -namespace std -{ - ostream& - operator<< (ostream& os, const ::butl::path& p) - { - using namespace build2; - - return os << (stream_verb (os).path < 1 - ? diag_relative (p) - : p.representation ()); - } - - ostream& - operator<< (ostream& os, const ::butl::process_path& p) - { - using namespace build2; - - if (p.empty ()) - os << "<empty>"; - else - { - // @@ Is there a reason not to print as a relative path as it is done - // for path (see above)? - // - os << p.recall_string (); - - if (!p.effect.empty ()) - os << '@' << p.effect.string (); // Suppress relative(). - } - - return os; - } -} - -namespace build2 -{ - // - // <build2/utility.hxx> - // - process_path argv0; - - const standard_version build_version (BUILD2_VERSION_STR); - - bool dry_run_option; - optional<bool> mtime_check_option; - - optional<path> config_sub; - optional<path> config_guess; - - void - check_build_version (const standard_version_constraint& c, const location& l) - { - if (!c.satisfies (build_version)) - fail (l) << "incompatible build2 version" << - info << "running " << build_version.string () << - info << "required " << c.string (); - } - - dir_path work; - dir_path home; - const dir_path* relative_base = &work; - - path - relative (const path_target& t) - { - const path& p (t.path ()); - assert (!p.empty ()); - return relative (p); - } - - string - diag_relative (const path& p, bool cur) - { - if (p.string () == "-") - return "<stdin>"; - - const path& b (*relative_base); - - if (p.absolute ()) - { - if (p == b) - return cur ? "." + p.separator_string () : string (); - -#ifndef _WIN32 - if (!home.empty ()) - { - if (p == home) - return "~" + p.separator_string (); - } -#endif - - path rb (relative (p)); - -#ifndef _WIN32 - if (!home.empty ()) - { - if (rb.relative ()) - { - // See if the original path with the ~/ shortcut is better that the - // relative to base. - // - if (p.sub (home)) - { - path rh (p.leaf (home)); - if (rb.size () > rh.size () + 2) // 2 for '~/' - return "~/" + move (rh).representation (); - } - } - else if (rb.sub (home)) - return "~/" + rb.leaf (home).representation (); - } - -#endif - - return move (rb).representation (); - } - - return p.representation (); - } - - process_path - run_search (const char*& args0, bool path_only, const location& l) - try - { - return process::path_search (args0, dir_path () /* fallback */, path_only); - } - catch (const process_error& e) - { - fail (l) << "unable to execute " << args0 << ": " << e << endf; - } - - process_path - run_search (const path& f, - bool init, - const dir_path& fallback, - bool path_only, - const location& l) - try - { - return process::path_search (f, init, fallback, path_only); - } - catch (const process_error& e) - { - fail (l) << "unable to execute " << f << ": " << e << endf; - } - - process_path - try_run_search (const path& f, - bool init, - const dir_path& fallback, - bool path_only) - { - return process::try_path_search (f, init, fallback, path_only); - } - - process - run_start (uint16_t verbosity, - const process_env& pe, - const char* args[], - int in, - int out, - bool err, - const dir_path& cwd, - const location& l) - try - { - assert (args[0] == pe.path->recall_string ()); - - if (verb >= verbosity) - print_process (args, 0); - - return process ( - *pe.path, - args, - in, - out, - (err ? 2 : 1), - (!cwd.empty () - ? cwd.string ().c_str () - : pe.cwd != nullptr ? pe.cwd->string ().c_str () : nullptr), - pe.vars); - } - catch (const process_error& e) - { - if (e.child) - { - // Note: run_finish() expects this exact message. - // - cerr << "unable to execute " << args[0] << ": " << e << endl; - - // In a multi-threaded program that fork()'ed but did not exec(), it is - // unwise to try to do any kind of cleanup (like unwinding the stack and - // running destructors). - // - exit (1); - } - else - fail (l) << "unable to execute " << args[0] << ": " << e << endf; - } - - bool - run_finish (const char* args[], - process& pr, - bool err, - const string& l, - const location& loc) - try - { - tracer trace ("run_finish"); - - if (pr.wait ()) - return true; - - const process_exit& e (*pr.exit); - - if (!e.normal ()) - fail (loc) << "process " << args[0] << " " << e; - - // Normall but non-zero exit status. - // - if (err) - { - // While we assuming diagnostics has already been issued (to STDERR), if - // that's not the case, it's a real pain to debug. So trace it. - // - l4 ([&]{trace << "process " << args[0] << " " << e;}); - - throw failed (); - } - - // Even if the user asked to suppress diagnostiscs, one error that we - // want to let through is the inability to execute the program itself. - // We cannot reserve a special exit status to signal this so we will - // just have to compare the output. This particular situation will - // result in a single error line printed by run_start() above. - // - if (l.compare (0, 18, "unable to execute ") == 0) - fail (loc) << l; - - return false; - } - catch (const process_error& e) - { - fail (loc) << "unable to execute " << args[0] << ": " << e << endf; - } - - const string empty_string; - const path empty_path; - const dir_path empty_dir_path; - const project_name empty_project_name; - - const optional<string> nullopt_string; - const optional<path> nullopt_path; - const optional<dir_path> nullopt_dir_path; - const optional<project_name> nullopt_project_name; - - void - append_options (cstrings& args, const lookup& l, const char* e) - { - if (l) - append_options (args, cast<strings> (l), e); - } - - void - append_options (strings& args, const lookup& l, const char* e) - { - if (l) - append_options (args, cast<strings> (l), e); - } - - void - hash_options (sha256& csum, const lookup& l) - { - if (l) - hash_options (csum, cast<strings> (l)); - } - - void - append_options (cstrings& args, const strings& sv, size_t n, const char* e) - { - if (n != 0) - { - args.reserve (args.size () + n); - - for (size_t i (0); i != n; ++i) - { - if (e == nullptr || e != sv[i]) - args.push_back (sv[i].c_str ()); - } - } - } - - void - append_options (strings& args, const strings& sv, size_t n, const char* e) - { - if (n != 0) - { - args.reserve (args.size () + n); - - for (size_t i (0); i != n; ++i) - { - if (e == nullptr || e != sv[i]) - args.push_back (sv[i]); - } - } - } - - void - hash_options (sha256& csum, const strings& sv, size_t n) - { - for (size_t i (0); i != n; ++i) - csum.append (sv[i]); - } - - bool - find_option (const char* o, const lookup& l, bool ic) - { - return l && find_option (o, cast<strings> (l), ic); - } - - bool - find_option (const char* o, const strings& strs, bool ic) - { - for (const string& s: strs) - if (ic ? casecmp (s, o) == 0 : s == o) - return true; - - return false; - } - - bool - find_option (const char* o, const cstrings& cstrs, bool ic) - { - for (const char* s: cstrs) - if (s != nullptr && (ic ? casecmp (s, o) : strcmp (s, o)) == 0) - return true; - - return false; - } - - bool - find_options (initializer_list<const char*> os, const lookup& l, bool ic) - { - return l && find_options (os, cast<strings> (l), ic); - } - - bool - find_options (initializer_list<const char*> os, const strings& strs, bool ic) - { - for (const string& s: strs) - for (const char* o: os) - if (ic ? casecmp (s, o) == 0 : s == o) - return true; - - return false; - } - - bool - find_options (initializer_list<const char*> os, - const cstrings& cstrs, - bool ic) - { - for (const char* s: cstrs) - if (s != nullptr) - for (const char* o: os) - if ((ic ? casecmp (s, o) : strcmp (s, o)) == 0) - return true; - - return false; - } - - const string* - find_option_prefix (const char* p, const lookup& l, bool ic) - { - return l ? find_option_prefix (p, cast<strings> (l), ic) : nullptr; - } - - const string* - find_option_prefix (const char* p, const strings& strs, bool ic) - { - size_t n (strlen (p)); - - for (const string& s: reverse_iterate (strs)) - if ((ic ? casecmp (s, p, n) : s.compare (0, n, p)) == 0) - return &s; - - return nullptr; - } - - const char* - find_option_prefix (const char* p, const cstrings& cstrs, bool ic) - { - size_t n (strlen (p)); - - for (const char* s: reverse_iterate (cstrs)) - if (s != nullptr && (ic ? casecmp (s, p, n) : strncmp (s, p, n)) == 0) - return s; - - return nullptr; - } - - const string* - find_option_prefixes (initializer_list<const char*> ps, - const lookup& l, - bool ic) - { - return l ? find_option_prefixes (ps, cast<strings> (l), ic) : nullptr; - } - - const string* - find_option_prefixes (initializer_list<const char*> ps, - const strings& strs, - bool ic) - { - for (const string& s: reverse_iterate (strs)) - for (const char* p: ps) - if ((ic - ? casecmp (s, p, strlen (p)) - : s.compare (0, strlen (p), p)) == 0) - return &s; - - return nullptr; - } - - const char* - find_option_prefixes (initializer_list<const char*> ps, - const cstrings& cstrs, - bool ic) - { - for (const char* s: reverse_iterate (cstrs)) - if (s != nullptr) - for (const char* p: ps) - if ((ic - ? casecmp (s, p, strlen (p)) - : strncmp (s, p, strlen (p))) == 0) - return s; - - return nullptr; - } - - string - apply_pattern (const char* s, const string* p) - { - if (p == nullptr || p->empty ()) - return s; - - size_t i (p->find ('*')); - assert (i != string::npos); - - string r (*p, 0, i++); - r.append (s); - r.append (*p, i, p->size () - i); - return r; - } - - void - init (const char* a0, - bool kg, bool dr, optional<bool> mc, - optional<path> cs, optional<path> cg) - { - // Build system driver process path. - // - argv0 = process::path_search (a0, true); - - keep_going = kg; - dry_run_option = dr; - mtime_check_option = mc; - - config_sub = move (cs); - config_guess = move (cg); - - // Figure out work and home directories. - // - try - { - work = dir_path::current_directory (); - } - catch (const system_error& e) - { - fail << "invalid current working directory: " << e; - } - - home = dir_path::home_directory (); - } -} |