diff options
| author | Alexander Karatarakis <alkarata@microsoft.com> | 2016-09-18 20:50:08 -0700 |
|---|---|---|
| committer | Alexander Karatarakis <alkarata@microsoft.com> | 2016-09-18 20:54:03 -0700 |
| commit | ccca198c1b1730b0241911cb56dc8e3504958b2a (patch) | |
| tree | a2dd9b8b087a09afdcecc5cbb3377bed15127eb2 /toolsrc/include | |
| download | vcpkg-ccca198c1b1730b0241911cb56dc8e3504958b2a.tar.gz vcpkg-ccca198c1b1730b0241911cb56dc8e3504958b2a.zip | |
Initial commit
Diffstat (limited to 'toolsrc/include')
| -rw-r--r-- | toolsrc/include/BinaryParagraph.h | 30 | ||||
| -rw-r--r-- | toolsrc/include/SourceParagraph.h | 20 | ||||
| -rw-r--r-- | toolsrc/include/StatusParagraph.h | 41 | ||||
| -rw-r--r-- | toolsrc/include/StatusParagraphs.h | 49 | ||||
| -rw-r--r-- | toolsrc/include/expected.h | 81 | ||||
| -rw-r--r-- | toolsrc/include/metrics.h | 19 | ||||
| -rw-r--r-- | toolsrc/include/opt_bool.h | 11 | ||||
| -rw-r--r-- | toolsrc/include/package_spec.h | 50 | ||||
| -rw-r--r-- | toolsrc/include/package_spec_parse_result.h | 34 | ||||
| -rw-r--r-- | toolsrc/include/post_build_lint.h | 8 | ||||
| -rw-r--r-- | toolsrc/include/triplet.h | 55 | ||||
| -rw-r--r-- | toolsrc/include/vcpkg.h | 37 | ||||
| -rw-r--r-- | toolsrc/include/vcpkg_Checks.h | 49 | ||||
| -rw-r--r-- | toolsrc/include/vcpkg_Commands.h | 67 | ||||
| -rw-r--r-- | toolsrc/include/vcpkg_Environment.h | 17 | ||||
| -rw-r--r-- | toolsrc/include/vcpkg_Files.h | 11 | ||||
| -rw-r--r-- | toolsrc/include/vcpkg_Graphs.h | 119 | ||||
| -rw-r--r-- | toolsrc/include/vcpkg_Strings.h | 58 | ||||
| -rw-r--r-- | toolsrc/include/vcpkg_System.h | 77 | ||||
| -rw-r--r-- | toolsrc/include/vcpkg_cmd_arguments.h | 36 | ||||
| -rw-r--r-- | toolsrc/include/vcpkg_paths.h | 29 | ||||
| -rw-r--r-- | toolsrc/include/vcpkglib_helpers.h | 12 |
22 files changed, 910 insertions, 0 deletions
diff --git a/toolsrc/include/BinaryParagraph.h b/toolsrc/include/BinaryParagraph.h new file mode 100644 index 000000000..88d6e84b1 --- /dev/null +++ b/toolsrc/include/BinaryParagraph.h @@ -0,0 +1,30 @@ +#pragma once + +#include <unordered_map> +#include "SourceParagraph.h" +#include "triplet.h" + +namespace vcpkg +{ + struct BinaryParagraph + { + BinaryParagraph(); + explicit BinaryParagraph(const std::unordered_map<std::string, std::string>& fields); + BinaryParagraph(const SourceParagraph& spgh, const triplet& target_triplet); + + std::string displayname() const; + + std::string fullstem() const; + + std::string dir() const; + + std::string name; + std::string version; + std::string description; + std::string maintainer; + triplet target_triplet; + std::vector<std::string> depends; + }; + + std::ostream& operator<<(std::ostream& os, const BinaryParagraph& pgh); +} diff --git a/toolsrc/include/SourceParagraph.h b/toolsrc/include/SourceParagraph.h new file mode 100644 index 000000000..72dca8324 --- /dev/null +++ b/toolsrc/include/SourceParagraph.h @@ -0,0 +1,20 @@ +#pragma once + +#include <vector> +#include <unordered_map> + +namespace vcpkg +{ + struct SourceParagraph + { + SourceParagraph(); + + explicit SourceParagraph(const std::unordered_map<std::string, std::string>& fields); + + std::string name; + std::string version; + std::string description; + std::string maintainer; + std::vector<std::string> depends; + }; +} diff --git a/toolsrc/include/StatusParagraph.h b/toolsrc/include/StatusParagraph.h new file mode 100644 index 000000000..1386bbdf4 --- /dev/null +++ b/toolsrc/include/StatusParagraph.h @@ -0,0 +1,41 @@ +#pragma once + +#include <unordered_map> +#include "BinaryParagraph.h" + +namespace vcpkg +{ + enum class install_state_t + { + error, + not_installed, + half_installed, + installed, + }; + + enum class want_t + { + error, + unknown, + install, + hold, + deinstall, + purge + }; + + struct StatusParagraph + { + StatusParagraph(); + explicit StatusParagraph(const std::unordered_map<std::string, std::string>& fields); + + BinaryParagraph package; + want_t want; + install_state_t state; + }; + + std::ostream& operator<<(std::ostream& os, const StatusParagraph& pgh); + + std::string to_string(install_state_t f); + + std::string to_string(want_t f); +} diff --git a/toolsrc/include/StatusParagraphs.h b/toolsrc/include/StatusParagraphs.h new file mode 100644 index 000000000..9446d432c --- /dev/null +++ b/toolsrc/include/StatusParagraphs.h @@ -0,0 +1,49 @@ +#pragma once +#include "StatusParagraph.h" +#include <memory> + +namespace vcpkg +{ + struct StatusParagraphs + { + StatusParagraphs(); + explicit StatusParagraphs(std::vector<std::unique_ptr<StatusParagraph>>&& ps); + + using container = std::vector<std::unique_ptr<StatusParagraph>>; + using iterator = container::reverse_iterator; + using const_iterator = container::const_reverse_iterator; + + const_iterator find(const std::string& name, const triplet& target_triplet) const; + iterator find(const std::string& name, const triplet& target_triplet); + iterator find_installed(const std::string& name, const triplet& target_triplet); + + iterator insert(std::unique_ptr<StatusParagraph>); + + friend std::ostream& operator<<(std::ostream&, const StatusParagraphs&); + + auto end() + { + return paragraphs.rend(); + } + + auto end() const + { + return paragraphs.rend(); + } + + auto begin() + { + return paragraphs.rbegin(); + } + + auto begin() const + { + return paragraphs.rbegin(); + } + + private: + std::vector<std::unique_ptr<StatusParagraph>> paragraphs; + }; + + std::ostream& operator<<(std::ostream&, const StatusParagraphs&); +} diff --git a/toolsrc/include/expected.h b/toolsrc/include/expected.h new file mode 100644 index 000000000..affabcc02 --- /dev/null +++ b/toolsrc/include/expected.h @@ -0,0 +1,81 @@ +#pragma once + +#include "vcpkg_Checks.h" + +namespace vcpkg +{ + template <class T> + class expected + { + public: + // Constructors are intentionally implicit + expected(const std::error_code& ec) : m_error_code(ec), m_t() + { + } + + expected(std::errc ec) : expected(std::make_error_code(ec)) + { + } + + expected(const T& t) : m_error_code(), m_t(t) + { + } + + expected(T&& t) : m_error_code(), m_t(std::move(t)) + { + } + + expected() : expected(std::error_code(), T()) + { + } + + expected(const expected&) = default; + expected(expected&&) = default; + expected& operator=(const expected&) = default; + expected& operator=(expected&&) = default; + + std::error_code error_code() const + { + return this->m_error_code; + } + + T&& get_or_throw() && + { + throw_if_error(); + return std::move(this->m_t); + } + + const T& get_or_throw() const & + { + throw_if_error(); + return this->m_t; + } + + const T* get() const + { + if (m_error_code) + { + return nullptr; + } + return &this->m_t; + } + + T* get() + { + if (m_error_code) + { + return nullptr; + } + return &this->m_t; + } + + private: + void throw_if_error() const + { + Checks::check_throw(!this->m_error_code, this->m_error_code.message().c_str()); + } + + std::error_code m_error_code; + T m_t; + }; +} diff --git a/toolsrc/include/metrics.h b/toolsrc/include/metrics.h new file mode 100644 index 000000000..52662cd97 --- /dev/null +++ b/toolsrc/include/metrics.h @@ -0,0 +1,19 @@ +#pragma once + +#include <string> + +namespace vcpkg +{ + void SetSendMetrics(bool should_send_metrics); + void SetPrintMetrics(bool should_print_metrics); + void SetUserInformation(const std::string& user_id, const std::string& first_use_time); + void InitUserInformation(std::string& user_id, std::string& first_use_time); + + void TrackMetric(const std::string& name, double value); + void TrackProperty(const std::string& name, const std::string& value); + void TrackProperty(const std::string& name, const std::wstring& value); + bool GetCompiledMetricsEnabled(); + + void Upload(const std::string& payload); + void Flush(); +} diff --git a/toolsrc/include/opt_bool.h b/toolsrc/include/opt_bool.h new file mode 100644 index 000000000..3856366c8 --- /dev/null +++ b/toolsrc/include/opt_bool.h @@ -0,0 +1,11 @@ +#pragma once + +namespace vcpkg +{ + enum class opt_bool + { + unspecified, + enabled, + disabled + }; +} diff --git a/toolsrc/include/package_spec.h b/toolsrc/include/package_spec.h new file mode 100644 index 000000000..b8ed1e088 --- /dev/null +++ b/toolsrc/include/package_spec.h @@ -0,0 +1,50 @@ +#pragma once +#include <string> +#include "package_spec_parse_result.h" +#include "triplet.h" +#include "expected.h" + +namespace vcpkg +{ + struct package_spec + { + std::string name; + triplet target_triplet; + + std::string dir() const; + }; + + expected<package_spec> parse(const std::string& spec, const triplet& default_target_triplet); + + std::string to_string(const package_spec& spec); + + std::string to_printf_arg(const package_spec& spec); + + bool operator==(const package_spec& left, const package_spec& right); + + std::ostream& operator<<(std::ostream& os, const package_spec& spec); +} //namespace vcpkg + +namespace std +{ + template <> + struct hash<vcpkg::package_spec> + { + size_t operator()(const vcpkg::package_spec& value) const + { + size_t hash = 17; + hash = hash * 31 + std::hash<std::string>()(value.name); + hash = hash * 31 + std::hash<vcpkg::triplet>()(value.target_triplet); + return hash; + } + }; + + template <> + struct equal_to<vcpkg::package_spec> + { + bool operator()(const vcpkg::package_spec& left, const vcpkg::package_spec& right) const + { + return left == right; + } + }; +} // namespace std diff --git a/toolsrc/include/package_spec_parse_result.h b/toolsrc/include/package_spec_parse_result.h new file mode 100644 index 000000000..e59622951 --- /dev/null +++ b/toolsrc/include/package_spec_parse_result.h @@ -0,0 +1,34 @@ +#pragma once +#include <system_error> + +namespace vcpkg +{ + enum class package_spec_parse_result + { + success = 0, + too_many_colons + }; + + struct package_spec_parse_result_category_impl final : std::error_category + { + virtual const char* name() const noexcept override; + + virtual std::string message(int ev) const noexcept override; + }; + + const std::error_category& package_spec_parse_result_category(); + + std::error_code make_error_code(package_spec_parse_result e); + + package_spec_parse_result to_package_spec_parse_result(int i); + + package_spec_parse_result to_package_spec_parse_result(std::error_code ec); +} + +// Enable implicit conversion to std::error_code +namespace std +{ + template <> + struct is_error_code_enum<vcpkg::package_spec_parse_result> : ::std::true_type + {}; +} diff --git a/toolsrc/include/post_build_lint.h b/toolsrc/include/post_build_lint.h new file mode 100644 index 000000000..bc916a7af --- /dev/null +++ b/toolsrc/include/post_build_lint.h @@ -0,0 +1,8 @@ +#pragma once +#include "package_spec.h" +#include "vcpkg_paths.h" + +namespace vcpkg +{ + void perform_all_checks(const package_spec& spec, const vcpkg_paths& paths); +} diff --git a/toolsrc/include/triplet.h b/toolsrc/include/triplet.h new file mode 100644 index 000000000..f9d1e9483 --- /dev/null +++ b/toolsrc/include/triplet.h @@ -0,0 +1,55 @@ +#pragma once + +#include <string> + +namespace vcpkg +{ + struct triplet + { + static const triplet X86_WINDOWS; + static const triplet X64_WINDOWS; + static const triplet X86_UWP; + static const triplet X64_UWP; + static const triplet ARM_UWP; + + std::string value; + + std::string architecture() const; + + std::string system() const; + }; + + bool operator==(const triplet& left, const triplet& right); + + bool operator!=(const triplet& left, const triplet& right); + + std::string to_string(const triplet& spec); + + std::string to_printf_arg(const triplet& spec); + + std::ostream& operator<<(std::ostream& os, const triplet& spec); +} + +namespace std +{ + template <> + struct hash<vcpkg::triplet> + { + size_t operator()(const vcpkg::triplet& t) const + { + std::hash<std::string> hasher; + size_t hash = 17; + hash = hash * 31 + hasher(t.value); + return hash; + } + }; + + template <> + struct equal_to<vcpkg::triplet> + { + bool operator()(const vcpkg::triplet& left, const vcpkg::triplet& right) const + { + return left == right; + } + }; +} // namespace std diff --git a/toolsrc/include/vcpkg.h b/toolsrc/include/vcpkg.h new file mode 100644 index 000000000..264d61fa9 --- /dev/null +++ b/toolsrc/include/vcpkg.h @@ -0,0 +1,37 @@ +#pragma once + +#include <filesystem> +#include <vector> +#include <unordered_map> +#include "package_spec.h" +#include "BinaryParagraph.h" +#include "StatusParagraphs.h" +#include "vcpkg_paths.h" + +namespace vcpkg +{ + namespace fs = std::tr2::sys; + + extern bool g_do_dry_run; + + std::vector<std::unordered_map<std::string, std::string>> get_paragraphs(const fs::path& control_path); + std::vector<std::unordered_map<std::string, std::string>> parse_paragraphs(const std::string& str); + std::string shorten_description(const std::string& desc); + + fs::path find_available_package(const vcpkg_paths& paths, const package_spec& spec); + fs::path find_available_port_file(const vcpkg_paths& paths, const package_spec& spec); + fs::path control_file_for_package(const fs::path& package_path); + + StatusParagraphs database_load_check(const vcpkg_paths& paths); + + std::vector<std::string> get_unmet_package_dependencies(const vcpkg_paths& paths, const package_spec& spec, const StatusParagraphs& status_db); + + void install_package(const vcpkg_paths& paths, const BinaryParagraph& binary_paragraph, StatusParagraphs& status_db); + void deinstall_package(const vcpkg_paths& paths, const package_spec& spec, StatusParagraphs& status_db); + + void search_file(const vcpkg_paths& paths, const std::string& file_substr, const StatusParagraphs& status_db); + + void binary_import(const vcpkg_paths& paths, const fs::path& include_directory, const fs::path& project_directory, const BinaryParagraph& control_file_data); + + const std::string& version(); +} // namespace vcpkg diff --git a/toolsrc/include/vcpkg_Checks.h b/toolsrc/include/vcpkg_Checks.h new file mode 100644 index 000000000..05bd0e729 --- /dev/null +++ b/toolsrc/include/vcpkg_Checks.h @@ -0,0 +1,49 @@ +#pragma once + +#include "vcpkg_Strings.h" + +namespace vcpkg {namespace Checks +{ + __declspec(noreturn) void unreachable(); + + // Part of the reason these exist is to not include extra headers in this one to avoid circular #includes. + _declspec(noreturn) void exit_with_message(const char* errorMessage); + + template <class...Args> + _declspec(noreturn) void exit_with_message(const char* errorMessageTemplate, const Args&... errorMessageArgs) + { + exit_with_message(Strings::format(errorMessageTemplate, errorMessageArgs...).c_str()); + } + + _declspec(noreturn) void throw_with_message(const char* errorMessage); + + template <class...Args> + _declspec(noreturn) void throw_with_message(const char* errorMessageTemplate, const Args&... errorMessageArgs) + { + throw_with_message(Strings::format(errorMessageTemplate, errorMessageArgs...)); + } + + void check_throw(bool expression, const char* errorMessage); + + template <class...Args> + void check_throw(bool expression, const char* errorMessageTemplate, const Args&... errorMessageArgs) + { + if (!expression) + { + // Only create the string if the expression is false + throw_with_message(Strings::format(errorMessageTemplate, errorMessageArgs...).c_str()); + } + } + + void check_exit(bool expression, const char* errorMessage); + + template <class...Args> + void check_exit(bool expression, const char* errorMessageTemplate, const Args&... errorMessageArgs) + { + if (!expression) + { + // Only create the string if the expression is false + exit_with_message(Strings::format(errorMessageTemplate, errorMessageArgs...).c_str()); + } + } +}} diff --git a/toolsrc/include/vcpkg_Commands.h b/toolsrc/include/vcpkg_Commands.h new file mode 100644 index 000000000..c706c131c --- /dev/null +++ b/toolsrc/include/vcpkg_Commands.h @@ -0,0 +1,67 @@ +#pragma once + +#include "vcpkg_cmd_arguments.h" +#include "vcpkg_paths.h" + +namespace vcpkg +{ + extern const char*const INTEGRATE_COMMAND_HELPSTRING; + + void print_usage(); + void print_example(const char* command_and_arguments); + void update_command(const vcpkg_cmd_arguments& args, const vcpkg_paths& paths); + + void build_command(const vcpkg_cmd_arguments& args, const vcpkg_paths& paths, const triplet& default_target_triplet); + void build_external_command(const vcpkg_cmd_arguments& args, const vcpkg_paths& paths, const triplet& default_target_triplet); + void install_command(const vcpkg_cmd_arguments& args, const vcpkg_paths& paths, const triplet& default_target_triplet); + void remove_command(const vcpkg_cmd_arguments& args, const vcpkg_paths& paths, const triplet& default_target_triplet); + + void edit_command(const vcpkg_cmd_arguments& args, const vcpkg_paths& paths, const triplet& default_target_triplet); + void create_command(const vcpkg_cmd_arguments& args, const vcpkg_paths& paths, const triplet& default_target_triplet); + + void search_command(const vcpkg_cmd_arguments& args, const vcpkg_paths& paths); + void list_command(const vcpkg_cmd_arguments& args, const vcpkg_paths& paths); + void import_command(const vcpkg_cmd_arguments& args, const vcpkg_paths& paths); + void owns_command(const vcpkg_cmd_arguments& args, const vcpkg_paths& paths); + void internal_test_command(const vcpkg_cmd_arguments& args, const vcpkg_paths& paths); + + void cache_command(const vcpkg_cmd_arguments& args, const vcpkg_paths& paths); + + void integrate_command(const vcpkg_cmd_arguments& args, const vcpkg_paths& paths); + + void help_command(const vcpkg_cmd_arguments& args, const vcpkg_paths& paths); + void help_topic_valid_triplet(const vcpkg_paths& paths); + + void version_command(const vcpkg_cmd_arguments& args); + void contact_command(const vcpkg_cmd_arguments& args); + + using command_type_a = void(*)(const vcpkg_cmd_arguments& args, const vcpkg_paths& paths, const triplet& default_target_triplet); + using command_type_b = void(*)(const vcpkg_cmd_arguments& args, const vcpkg_paths& paths); + using command_type_c = void(*)(const vcpkg_cmd_arguments& args); + + template <class T> + struct package_name_and_function + { + std::string name; + T function; + }; + + const std::vector<package_name_and_function<command_type_a>>& get_available_commands_type_a(); + const std::vector<package_name_and_function<command_type_b>>& get_available_commands_type_b(); + const std::vector<package_name_and_function<command_type_c>>& get_available_commands_type_c(); + + template <typename T> + T find_command(const std::string& command_name, const std::vector<package_name_and_function<T>> available_commands) + { + for (const package_name_and_function<T>& cmd : available_commands) + { + if (cmd.name == command_name) + { + return cmd.function; + } + } + + // not found + return nullptr; + } +} diff --git a/toolsrc/include/vcpkg_Environment.h b/toolsrc/include/vcpkg_Environment.h new file mode 100644 index 000000000..877ac7deb --- /dev/null +++ b/toolsrc/include/vcpkg_Environment.h @@ -0,0 +1,17 @@ +#pragma once +#include "vcpkg_paths.h" + +namespace vcpkg {namespace Environment +{ + void ensure_nuget_on_path(const vcpkg_paths& paths); + + void ensure_git_on_path(const vcpkg_paths& paths); + + void ensure_cmake_on_path(const vcpkg_paths& paths); + + inline void ensure_utilities_on_path(const vcpkg_paths& paths) + { + ensure_cmake_on_path(paths); + ensure_git_on_path(paths); + } +}} diff --git a/toolsrc/include/vcpkg_Files.h b/toolsrc/include/vcpkg_Files.h new file mode 100644 index 000000000..d23742f74 --- /dev/null +++ b/toolsrc/include/vcpkg_Files.h @@ -0,0 +1,11 @@ +#pragma once + +#include "expected.h" +#include <filesystem> + +namespace vcpkg {namespace Files +{ + void check_is_directory(const std::tr2::sys::path& dirpath); + + expected<std::string> get_contents(const std::tr2::sys::path& file_path) noexcept; +}} diff --git a/toolsrc/include/vcpkg_Graphs.h b/toolsrc/include/vcpkg_Graphs.h new file mode 100644 index 000000000..81b189f0e --- /dev/null +++ b/toolsrc/include/vcpkg_Graphs.h @@ -0,0 +1,119 @@ +#pragma once + +#include <unordered_map> + +namespace vcpkg { namespace Graphs +{ + enum class ExplorationStatus + { + // We have not visited this vertex + NOT_EXPLORED, + + // We have visited this vertex but haven't visited all vertices in its subtree + PARTIALLY_EXPLORED, + + // We have visited this vertex and all vertices in its subtree + FULLY_EXPLORED + }; + + template <class V> + class Graph + { + static void find_topological_sort_internal(V vertex, + ExplorationStatus& status, + const std::unordered_map<V, std::vector<V>>& adjacency_list, + std::unordered_map<V, ExplorationStatus>& exploration_status, + std::vector<V>& sorted) + { + status = ExplorationStatus::PARTIALLY_EXPLORED; + + for (V neighbour : adjacency_list.at(vertex)) + { + ExplorationStatus& neighbour_status = exploration_status[neighbour]; + if (neighbour_status == ExplorationStatus::NOT_EXPLORED) + { + find_topological_sort_internal(neighbour, neighbour_status, adjacency_list, exploration_status, sorted); + } + else if (neighbour_status == ExplorationStatus::PARTIALLY_EXPLORED) + { + throw std::runtime_error("cycle in graph"); + } + } + + status = ExplorationStatus::FULLY_EXPLORED; + sorted.push_back(vertex); + } + + public: + + void add_vertex(V v) + { + this->vertices[v]; + } + + // TODO: Change with iterators + void add_vertices(const std::vector<V>& vs) + { + for (const V& v : vs) + { + this->vertices[v]; + } + } + + void add_edge(V u, V v) + { + this->vertices[v]; + this->vertices[u].push_back(v); + } + + std::vector<V> find_topological_sort() const + { + std::unordered_map<V, int> indegrees = count_indegrees(); + + std::vector<V> sorted; + sorted.reserve(indegrees.size()); + + std::unordered_map<V, ExplorationStatus> exploration_status; + exploration_status.reserve(indegrees.size()); + + for (auto& pair : indegrees) + { + if (pair.second == 0) // Starting from vertices with indegree == 0. Not required. + { + V vertex = pair.first; + ExplorationStatus& status = exploration_status[vertex]; + if (status == ExplorationStatus::NOT_EXPLORED) + { + find_topological_sort_internal(vertex, status, this->vertices, exploration_status, sorted); + } + } + } + + return sorted; + } + + std::unordered_map<V, int> count_indegrees() const + { + std::unordered_map<V, int> indegrees; + + for (auto& pair : this->vertices) + { + indegrees[pair.first]; + for (V neighbour : pair.second) + { + ++indegrees[neighbour]; + } + } + + return indegrees; + } + + const std::unordered_map<V, std::vector<V>>& adjacency_list() const + { + return this->vertices; + } + + private: + std::unordered_map<V, std::vector<V>> vertices; + }; +}} diff --git a/toolsrc/include/vcpkg_Strings.h b/toolsrc/include/vcpkg_Strings.h new file mode 100644 index 000000000..f4b989292 --- /dev/null +++ b/toolsrc/include/vcpkg_Strings.h @@ -0,0 +1,58 @@ +#pragma once + +#include <string> + +namespace vcpkg {namespace Strings {namespace details +{ + inline const char* to_printf_arg(const std::string& s) + { + return s.c_str(); + } + + inline const char* to_printf_arg(const char* s) + { + return s; + } + + inline int to_printf_arg(const int s) + { + return s; + } + + std::string format_internal(const char* fmtstr, ...); + + inline const wchar_t* to_wprintf_arg(const std::wstring& s) + { + return s.c_str(); + } + + inline const wchar_t* to_wprintf_arg(const wchar_t* s) + { + return s; + } + + std::wstring format_internal(const wchar_t* fmtstr, ...); +}}} + +namespace vcpkg {namespace Strings +{ + template <class...Args> + std::string format(const char* fmtstr, const Args&...args) + { + using vcpkg::Strings::details::to_printf_arg; + return details::format_internal(fmtstr, to_printf_arg(to_printf_arg(args))...); + } + + template <class...Args> + std::wstring format(const wchar_t* fmtstr, const Args&...args) + { + using vcpkg::Strings::details::to_wprintf_arg; + return details::format_internal(fmtstr, to_wprintf_arg(to_wprintf_arg(args))...); + } + + std::wstring utf8_to_utf16(const std::string& s); + + std::string utf16_to_utf8(const std::wstring& w); + + std::string::const_iterator case_insensitive_find(const std::string& s, const std::string& pattern); +}} diff --git a/toolsrc/include/vcpkg_System.h b/toolsrc/include/vcpkg_System.h new file mode 100644 index 000000000..f47fc9aab --- /dev/null +++ b/toolsrc/include/vcpkg_System.h @@ -0,0 +1,77 @@ +#pragma once + +#include "vcpkg_Strings.h" + +#include <filesystem> + +namespace vcpkg {namespace System +{ + std::tr2::sys::path get_exe_path_of_current_process(); + + struct exit_code_and_output + { + int exit_code; + std::string output; + }; + + int cmd_execute(const wchar_t* cmd_line); + + inline int cmd_execute(const std::wstring& cmd_line) + { + return cmd_execute(cmd_line.c_str()); + } + + exit_code_and_output cmd_execute_and_capture_output(const wchar_t* cmd_line); + + inline exit_code_and_output cmd_execute_and_capture_output(const std::wstring& cmd_line) + { + return cmd_execute_and_capture_output(cmd_line.c_str()); + } + + enum class color + { + success = 10, + error = 12, + warning = 14, + }; + + void print(const char* message); + void println(const char* message); + void print(color c, const char* message); + void println(color c, const char* message); + + template <class...Args> + void print(const char* messageTemplate, const Args&... messageArgs) + { + return print(Strings::format(messageTemplate, messageArgs...).c_str()); + } + + template <class...Args> + void print(color c, const char* messageTemplate, const Args&... messageArgs) + { + return print(c, Strings::format(messageTemplate, messageArgs...).c_str()); + } + + template <class...Args> + void println(const char* messageTemplate, const Args&... messageArgs) + { + return println(Strings::format(messageTemplate, messageArgs...).c_str()); + } + + template <class...Args> + void println(color c, const char* messageTemplate, const Args&... messageArgs) + { + return println(c, Strings::format(messageTemplate, messageArgs...).c_str()); + } + + struct Stopwatch + { + int64_t start_time, end_time, freq; + + void start(); + void stop(); + double microseconds() const; + }; + + std::wstring wdupenv_str(const wchar_t* varname) noexcept; +}} diff --git a/toolsrc/include/vcpkg_cmd_arguments.h b/toolsrc/include/vcpkg_cmd_arguments.h new file mode 100644 index 000000000..0df3d1222 --- /dev/null +++ b/toolsrc/include/vcpkg_cmd_arguments.h @@ -0,0 +1,36 @@ +#pragma once + +#include <memory> +#include <vector> +#include <unordered_set> +#include "opt_bool.h" +#include "package_spec.h" +#include "vcpkg_paths.h" +#include "StatusParagraphs.h" + +namespace vcpkg +{ + struct vcpkg_cmd_arguments + { + static vcpkg_cmd_arguments create_from_command_line(const int argc, const wchar_t* const* const argv); + + static vcpkg_cmd_arguments create_from_arg_sequence(const std::string* arg_begin, const std::string* arg_end); + + std::unique_ptr<std::string> vcpkg_root_dir; + std::unique_ptr<std::string> target_triplet; + opt_bool debug = opt_bool::unspecified; + opt_bool sendmetrics = opt_bool::unspecified; + opt_bool printmetrics = opt_bool::unspecified; + + std::string command; + std::vector<std::string> command_arguments; + std::unordered_set<std::string> check_and_get_optional_command_arguments(const std::vector<std::string>& valid_options) const; + + void check_max_args(size_t arg_count, const char* example_text = nullptr) const; + std::vector<package_spec> parse_all_arguments_as_package_specs(const triplet& default_target_triplet, const char* example_text = nullptr) const; + std::vector<package_spec> extract_package_specs_with_unmet_dependencies(const vcpkg_paths& paths, const triplet& default_target_triplet, const StatusParagraphs& status_db) const; + + private: + std::unordered_set<std::string> optional_command_arguments; + }; +} diff --git a/toolsrc/include/vcpkg_paths.h b/toolsrc/include/vcpkg_paths.h new file mode 100644 index 000000000..58ab45bc5 --- /dev/null +++ b/toolsrc/include/vcpkg_paths.h @@ -0,0 +1,29 @@ +#pragma once +#include <filesystem> +#include "expected.h" + +namespace vcpkg +{ + struct vcpkg_paths + { + static expected<vcpkg_paths> create(const std::tr2::sys::path& vcpkg_root_dir); + + std::tr2::sys::path root; + std::tr2::sys::path packages; + std::tr2::sys::path buildtrees; + std::tr2::sys::path downloads; + std::tr2::sys::path ports; + std::tr2::sys::path installed; + std::tr2::sys::path triplets; + + std::tr2::sys::path buildsystems; + std::tr2::sys::path buildsystems_msbuild_targets; + + std::tr2::sys::path vcpkg_dir; + std::tr2::sys::path vcpkg_dir_status_file; + std::tr2::sys::path vcpkg_dir_info; + std::tr2::sys::path vcpkg_dir_updates; + + std::tr2::sys::path ports_cmake; + }; +} diff --git a/toolsrc/include/vcpkglib_helpers.h b/toolsrc/include/vcpkglib_helpers.h new file mode 100644 index 000000000..e15b59b0b --- /dev/null +++ b/toolsrc/include/vcpkglib_helpers.h @@ -0,0 +1,12 @@ +#pragma once + +#include <unordered_map> + +namespace vcpkg {namespace details +{ + void optional_field(const std::unordered_map<std::string, std::string>& fields, std::string& out, const std::string& fieldname); + + void required_field(const std::unordered_map<std::string, std::string>& fields, std::string& out, const std::string& fieldname); + + void parse_depends(const std::string& depends_string, std::vector<std::string>& out); +}} |
