// file : libbuild2/utility.ixx -*- C++ -*- // license : MIT; see accompanying LICENSE file #include <cstring> // strlen() strchr() namespace build2 { inline bool run_wait (cstrings& args, process& pr, const location& loc) { return run_wait (args.data (), pr, loc); } // Note: currently this function is also used in a run() implementations. // LIBBUILD2_SYMEXPORT bool run_finish_impl (const char*[], process&, bool error, const string&, const location& = location ()); inline void run_finish (const char* args[], process& pr, const string& l, const location& loc) { run_finish_impl (args, pr, true /* error */, l, loc); } inline void run_finish (cstrings& args, process& pr, const location& loc) { run_finish (args.data (), pr, string (), loc); } inline bool run_finish_code (const char* args[], process& pr, const string& l, const location& loc) { return run_finish_impl (args, pr, false /* error */, l, loc); } inline void hash_path (sha256& cs, const path& p, const dir_path& prefix) { // Note: for efficiency we don't use path::leaf() and "skip" the prefix // without copying. // const char* s (p.string ().c_str ()); if (!prefix.empty () && p.sub (prefix)) { s += prefix.size (); // Does not include trailing slash except for root. if (path::traits_type::is_separator (*s)) ++s; } cs.append (s); } template <typename T> inline void append_options (cstrings& args, T& s, const variable& var, const char* e) { append_options (args, s[var], e); } template <typename T> inline void append_options (strings& args, T& s, const variable& var, const char* e) { append_options (args, s[var], e); } template <typename T> inline void append_options (sha256& csum, T& s, const variable& var) { append_options (csum, s[var]); } template <typename T> inline void append_options (cstrings& args, T& s, const char* var, const char* e) { append_options (args, s[var], e); } template <typename T> inline void append_options (strings& args, T& s, const char* var, const char* e) { append_options (args, s[var], e); } template <typename T> inline void append_options (sha256& csum, T& s, const char* var) { append_options (csum, s[var]); } inline void append_options (cstrings& args, const strings& sv, const char* e) { if (size_t n = sv.size ()) append_options (args, sv, n, e); } inline void append_options (strings& args, const strings& sv, const char* e) { if (size_t n = sv.size ()) append_options (args, sv, n, e); } inline void append_options (sha256& csum, const strings& sv) { if (size_t n = sv.size ()) append_options (csum, sv, n); } template <typename T> inline bool find_option (const char* o, T& s, const variable& var, bool ic) { return find_option (o, s[var], ic); } template <typename T> inline bool find_option (const char* o, T& s, const char* var, bool ic) { return find_option (o, s[var], ic); } inline bool compare_option (const char* o, const char* s, bool ic) { return s != nullptr && (ic ? icasecmp (s, o) : strcmp (s, o)) == 0; } inline bool compare_option (const char* o, const string& s, bool ic) { return ic ? icasecmp (s, o) == 0 : s == o; } template <typename I> inline I find_option (const char* o, I b, I e, bool ic) { for (; b != e; ++b) if (compare_option (o, *b, ic)) return b; return e; } template <typename T> inline bool find_options (const initializer_list<const char*>& os, T& s, const variable& var, bool ic) { return find_options (os, s[var], ic); } template <typename T> inline bool find_options (const initializer_list<const char*>& os, T& s, const char* var, bool ic) { return find_options (os, s[var], ic); } template <typename T> inline const string* find_option_prefix (const char* p, T& s, const variable& var, bool ic) { return find_option_prefix (p, s[var], ic); } template <typename T> inline const string* find_option_prefix (const char* p, T& s, const char* var, bool ic) { return find_option_prefix (p, s[var], ic); } inline bool compare_option_prefix (const char* p, size_t n, const char* s, bool ic) { return s != nullptr && (ic ? icasecmp (s, p, n) : strncmp (s, p, n)) == 0; } inline bool compare_option_prefix (const char* p, size_t n, const string& s, bool ic) { return (ic ? icasecmp (s, p, n) : s.compare (0, n, p)) == 0; } template <typename I> inline I find_option_prefix (const char* p, I b, I e, bool ic) { size_t n (strlen (p)); for (; b != e; ++b) if (compare_option_prefix (p, n, *b, ic)) return b; return e; } template <typename T> inline const string* find_option_prefixes (const initializer_list<const char*>& ps, T& s, const variable& var, bool ic) { return find_option_prefixes (ps, s[var], ic); } template <typename T> inline const string* find_option_prefixes (const initializer_list<const char*>& ps, T& s, const char* var, bool ic) { return find_option_prefixes (ps, s[var], ic); } // hash_environment() // inline void hash_environment (sha256& cs, const char* n) { cs.append (n); if (optional<string> v = getenv (n)) cs.append (*v); } inline void hash_environment (sha256& cs, const string& n) { hash_environment (cs, n.c_str ()); } inline void hash_environment (sha256& cs, initializer_list<const char*> ns) { for (const char* n: ns) hash_environment (cs, n); } inline string hash_environment (initializer_list<const char*> ns) { sha256 cs; hash_environment (cs, ns); return cs.string (); } inline void hash_environment (sha256& cs, const cstrings& ns) { for (const char* n: ns) hash_environment (cs, n); } inline string hash_environment (const cstrings& ns) { sha256 cs; hash_environment (cs, ns); return cs.string (); } inline void hash_environment (sha256& cs, const strings& ns) { for (const string& n: ns) hash_environment (cs, n); } inline string hash_environment (const strings& ns) { sha256 cs; hash_environment (cs, ns); return cs.string (); } inline void hash_environment (sha256& cs, const char* const* ns) { if (ns != nullptr) { for (; *ns != nullptr; ++ns) hash_environment (cs, *ns); } } inline string hash_environment (const char* const* ns) { sha256 cs; hash_environment (cs, ns); return cs.string (); } // find_stem() // inline size_t find_stem (const string& s, size_t s_p, size_t s_n, const char* stem, const char* seps) { auto sep = [seps] (char c) -> bool { return strchr (seps, c) != nullptr; }; size_t m (strlen (stem)); size_t p (s.find (stem, s_p, m)); return (p != string::npos && ( p == s_p || sep (s[p - 1])) && // Separated beginning. ((p + m) == s_n || sep (s[p + m]))) // Separated end. ? p : string::npos; } }