diff --git a/toolsrc/CMakeLists.txt b/toolsrc/CMakeLists.txt index 342765c1c..706162bd3 100644 --- a/toolsrc/CMakeLists.txt +++ b/toolsrc/CMakeLists.txt @@ -18,7 +18,7 @@ If you would like to try anyway, set VCPKG_ALLOW_APPLE_CLANG.") elseif(CMAKE_CXX_COMPILER_ID MATCHES "[Cc]lang") set(CLANG 1) elseif(MSVC) - add_compile_options(/std:c++latest) + add_compile_options(/std:c++17) else() message(FATAL_ERROR "Unknown compiler: ${CMAKE_CXX_COMPILER_ID}") endif() @@ -59,8 +59,17 @@ elseif(CLANG) target_link_libraries(vcpkg PRIVATE c++experimental) endif() -if(WIN32) - target_link_libraries(vcpkg PRIVATE bcrypt) +if(MSVC) + get_target_property(_srcs vcpkg SOURCES) + + if(NOT CMAKE_GENERATOR MATCHES "Visual Studio .*") + set_property(SOURCE src/pch.cpp APPEND PROPERTY OBJECT_OUTPUTS "${CMAKE_CURRENT_BINARY_DIR}/pch.pch") + set_property(SOURCE ${_srcs} APPEND PROPERTY OBJECT_DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/pch.pch") + endif() + + set_source_files_properties(src/pch.cpp PROPERTIES COMPILE_FLAGS "/Ycpch.h") + target_sources(vcpkg PRIVATE src/pch.cpp) + target_compile_options(vcpkg PRIVATE /Yupch.h /FIpch.h /Zm200) endif() set(THREADS_PREFER_PTHREAD_FLAG ON) diff --git a/toolsrc/include/pch.h b/toolsrc/include/pch.h index 9c9deeb3f..fa2c2bb72 100644 --- a/toolsrc/include/pch.h +++ b/toolsrc/include/pch.h @@ -1,5 +1,15 @@ #pragma once +#if defined(_MSC_VER) && _MSC_VER < 1911 +// [[nodiscard]] is not recognized before VS 2017 version 15.3 +#pragma warning(disable : 5030) +#endif + +#if defined(__GNUC__) && __GNUC__ < 7 +// [[nodiscard]] is not recognized before GCC version 7 +#pragma GCC diagnostic ignored "-Wattributes" +#endif + #if defined(_WIN32) #define NOMINMAX #define WIN32_LEAN_AND_MEAN diff --git a/toolsrc/include/vcpkg/base/checks.h b/toolsrc/include/vcpkg/base/checks.h index bceee3428..3c0c073d2 100644 --- a/toolsrc/include/vcpkg/base/checks.h +++ b/toolsrc/include/vcpkg/base/checks.h @@ -6,7 +6,7 @@ namespace vcpkg::Checks { - void register_console_ctrl_handler(); + void register_global_shutdown_handler(void (*func)()); // Indicate that an internal error has occurred and exit the tool. This should be used when invariants have been // broken. @@ -21,7 +21,7 @@ namespace vcpkg::Checks [[noreturn]] inline void exit_success(const LineInfo& line_info) { exit_with_code(line_info, EXIT_SUCCESS); } // Display an error message to the user and exit the tool. - [[noreturn]] void exit_with_message(const LineInfo& line_info, const CStringView error_message); + [[noreturn]] void exit_with_message(const LineInfo& line_info, StringView error_message); template // Display an error message to the user and exit the tool. @@ -36,7 +36,7 @@ namespace vcpkg::Checks void check_exit(const LineInfo& line_info, bool expression); - void check_exit(const LineInfo& line_info, bool expression, const CStringView error_message); + void check_exit(const LineInfo& line_info, bool expression, StringView error_message); template void check_exit(const LineInfo& line_info, diff --git a/toolsrc/include/vcpkg/base/chrono.h b/toolsrc/include/vcpkg/base/chrono.h index 6f6e2b317..26294fdf8 100644 --- a/toolsrc/include/vcpkg/base/chrono.h +++ b/toolsrc/include/vcpkg/base/chrono.h @@ -1,8 +1,10 @@ #pragma once +#include +#include + #include #include -#include namespace vcpkg::Chrono { @@ -21,6 +23,7 @@ namespace vcpkg::Chrono } std::string to_string() const; + void to_string(std::string& into) const; private: std::chrono::high_resolution_clock::time_point::duration m_duration; @@ -41,6 +44,7 @@ namespace vcpkg::Chrono double microseconds() const { return elapsed().as>().count(); } std::string to_string() const; + void to_string(std::string& into) const; private: std::chrono::high_resolution_clock::time_point m_start_tick; @@ -65,5 +69,7 @@ namespace vcpkg::Chrono mutable tm m_tm; }; + tm get_current_date_time(); + tm get_current_date_time_local(); } diff --git a/toolsrc/include/vcpkg/base/cstringview.h b/toolsrc/include/vcpkg/base/cstringview.h index f285aa36c..d49bfc82f 100644 --- a/toolsrc/include/vcpkg/base/cstringview.h +++ b/toolsrc/include/vcpkg/base/cstringview.h @@ -1,6 +1,6 @@ #pragma once -#include +#include #include namespace vcpkg @@ -14,6 +14,8 @@ namespace vcpkg constexpr const char* c_str() const { return cstr; } + void to_string(std::string& str) const { str.append(cstr); } + private: const char* cstr; }; diff --git a/toolsrc/include/vcpkg/base/expected.h b/toolsrc/include/vcpkg/base/expected.h index e20f723db..c273d71e6 100644 --- a/toolsrc/include/vcpkg/base/expected.h +++ b/toolsrc/include/vcpkg/base/expected.h @@ -1,6 +1,7 @@ #pragma once #include +#include #include @@ -20,13 +21,34 @@ namespace vcpkg const Err& error() const { return m_err; } Err& error() { return m_err; } - CStringView to_string() const { return "value was error"; } + StringLiteral to_string() const { return "value was error"; } private: bool m_is_error; Err m_err; }; + template<> + struct ErrorHolder + { + ErrorHolder() : m_is_error(false) {} + template + ErrorHolder(U&& err) : m_is_error(true), m_err(std::forward(err)) + { + } + + bool has_error() const { return m_is_error; } + + const std::string& error() const { return m_err; } + std::string& error() { return m_err; } + + const std::string& to_string() const { return m_err; } + + private: + bool m_is_error; + std::string m_err; + }; + template<> struct ErrorHolder { @@ -38,12 +60,21 @@ namespace vcpkg const std::error_code& error() const { return m_err; } std::error_code& error() { return m_err; } - CStringView to_string() const { return m_err.message(); } + std::string to_string() const { return m_err.message(); } private: std::error_code m_err; }; + struct ExpectedLeftTag + { + }; + struct ExpectedRightTag + { + }; + constexpr ExpectedLeftTag expected_left_tag; + constexpr ExpectedRightTag expected_right_tag; + template class ExpectedT { @@ -52,11 +83,11 @@ namespace vcpkg // Constructors are intentionally implicit - ExpectedT(const S& s) : m_s(s) {} - ExpectedT(S&& s) : m_s(std::move(s)) {} + ExpectedT(const S& s, ExpectedRightTag = {}) : m_s(s) {} + ExpectedT(S&& s, ExpectedRightTag = {}) : m_s(std::move(s)) {} - ExpectedT(const T& t) : m_t(t) {} - ExpectedT(T&& t) : m_t(std::move(t)) {} + ExpectedT(const T& t, ExpectedLeftTag = {}) : m_t(t) {} + ExpectedT(T&& t, ExpectedLeftTag = {}) : m_t(std::move(t)) {} ExpectedT(const ExpectedT&) = default; ExpectedT(ExpectedT&&) = default; diff --git a/toolsrc/include/vcpkg/base/graphs.h b/toolsrc/include/vcpkg/base/graphs.h index 6cff75ad3..46831a911 100644 --- a/toolsrc/include/vcpkg/base/graphs.h +++ b/toolsrc/include/vcpkg/base/graphs.h @@ -2,10 +2,11 @@ #include #include +#include #include #include -#include +#include namespace vcpkg::Graphs { @@ -66,12 +67,12 @@ namespace vcpkg::Graphs case ExplorationStatus::FULLY_EXPLORED: return; case ExplorationStatus::PARTIALLY_EXPLORED: { - System::println("Cycle detected within graph at %s:", f.to_string(vertex)); + System::print2("Cycle detected within graph at ", f.to_string(vertex), ":\n"); for (auto&& node : exploration_status) { if (node.second == ExplorationStatus::PARTIALLY_EXPLORED) { - System::println(" %s", f.to_string(node.first)); + System::print2(" ", f.to_string(node.first), '\n'); } } Checks::exit_fail(VCPKG_LINE_INFO); diff --git a/toolsrc/include/vcpkg/base/lineinfo.h b/toolsrc/include/vcpkg/base/lineinfo.h index e0eb8bec9..2f03fef16 100644 --- a/toolsrc/include/vcpkg/base/lineinfo.h +++ b/toolsrc/include/vcpkg/base/lineinfo.h @@ -6,13 +6,15 @@ namespace vcpkg { struct LineInfo { - int line_number; - const char* file_name; - - constexpr LineInfo() noexcept : line_number(0), file_name("") {} - constexpr LineInfo(const int lineno, const char* filename) : line_number(lineno), file_name(filename) {} + constexpr LineInfo() noexcept : m_line_number(0), m_file_name("") {} + constexpr LineInfo(const int lineno, const char* filename) : m_line_number(lineno), m_file_name(filename) {} std::string to_string() const; + void to_string(std::string& out) const; + + private: + int m_line_number; + const char* m_file_name; }; } diff --git a/toolsrc/include/vcpkg/base/optional.h b/toolsrc/include/vcpkg/base/optional.h index 6b84b10aa..4d386a961 100644 --- a/toolsrc/include/vcpkg/base/optional.h +++ b/toolsrc/include/vcpkg/base/optional.h @@ -1,6 +1,9 @@ #pragma once -#include +#include + +#include +#include namespace vcpkg { @@ -13,25 +16,146 @@ namespace vcpkg namespace details { - template + template::value> struct OptionalStorage { - constexpr OptionalStorage() noexcept : m_is_present(false), m_t() {} + constexpr OptionalStorage() noexcept : m_is_present(false), m_inactive() {} constexpr OptionalStorage(const T& t) : m_is_present(true), m_t(t) {} constexpr OptionalStorage(T&& t) : m_is_present(true), m_t(std::move(t)) {} + ~OptionalStorage() noexcept + { + if (m_is_present) m_t.~T(); + } + + OptionalStorage(const OptionalStorage& o) : m_is_present(o.m_is_present), m_inactive() + { + if (m_is_present) new (&m_t) T(o.m_t); + } + + OptionalStorage(OptionalStorage&& o) : m_is_present(o.m_is_present), m_inactive() + { + if (m_is_present) + { + new (&m_t) T(std::move(o.m_t)); + } + } + + OptionalStorage& operator=(const OptionalStorage& o) + { + if (m_is_present && o.m_is_present) + { + m_t = o.m_t; + } + else if (!m_is_present && o.m_is_present) + { + m_is_present = true; + new (&m_t) T(o.m_t); + } + else if (m_is_present && !o.m_is_present) + { + clear(); + } + return *this; + } + + OptionalStorage& operator=(OptionalStorage&& o) + { + if (m_is_present && o.m_is_present) + { + m_t = std::move(o.m_t); + } + else if (!m_is_present && o.m_is_present) + { + m_is_present = true; + new (&m_t) T(std::move(o.m_t)); + } + else if (m_is_present && !o.m_is_present) + { + clear(); + } + return *this; + } + constexpr bool has_value() const { return m_is_present; } const T& value() const { return this->m_t; } T& value() { return this->m_t; } private: + void clear() + { + m_is_present = false; + m_t.~T(); + m_inactive = '\0'; + } + bool m_is_present; - T m_t; + union { + char m_inactive; + T m_t; + }; }; template - struct OptionalStorage + struct OptionalStorage + { + constexpr OptionalStorage() noexcept : m_is_present(false), m_inactive() {} + constexpr OptionalStorage(T&& t) : m_is_present(true), m_t(std::move(t)) {} + + ~OptionalStorage() noexcept + { + if (m_is_present) m_t.~T(); + } + + OptionalStorage(OptionalStorage&& o) : m_is_present(o.m_is_present), m_inactive() + { + if (m_is_present) + { + new (&m_t) T(std::move(o.m_t)); + } + } + + OptionalStorage& operator=(OptionalStorage&& o) + { + if (m_is_present && o.m_is_present) + { + m_t = std::move(o.m_t); + } + else if (!m_is_present && o.m_is_present) + { + m_is_present = true; + new (&m_t) T(std::move(o.m_t)); + } + else if (m_is_present && !o.m_is_present) + { + clear(); + } + return *this; + } + + constexpr bool has_value() const { return m_is_present; } + + const T& value() const { return this->m_t; } + T& value() { return this->m_t; } + + private: + void clear() + { + m_is_present = false; + m_t.~T(); + m_inactive = '\0'; + } + + bool m_is_present; + union { + char m_inactive; + T m_t; + }; + }; + + template + struct OptionalStorage { constexpr OptionalStorage() noexcept : m_t(nullptr) {} constexpr OptionalStorage(T& t) : m_t(&t) {} @@ -43,6 +167,9 @@ namespace vcpkg private: T* m_t; }; + + // Note: implemented in checks.cpp to cut the header dependency + void exit_if_null(bool b, const LineInfo& line_info); } template @@ -53,26 +180,26 @@ namespace vcpkg // Constructors are intentionally implicit constexpr Optional(NullOpt) {} - template - Optional(U&& t) : m_base(std::forward(t)) + template, Optional>::value>> + constexpr Optional(U&& t) : m_base(std::forward(t)) { } T&& value_or_exit(const LineInfo& line_info) && { - this->exit_if_null(line_info); + details::exit_if_null(this->m_base.has_value(), line_info); return std::move(this->m_base.value()); } T& value_or_exit(const LineInfo& line_info) & { - this->exit_if_null(line_info); + details::exit_if_null(this->m_base.has_value(), line_info); return this->m_base.value(); } const T& value_or_exit(const LineInfo& line_info) const& { - this->exit_if_null(line_info); + details::exit_if_null(this->m_base.has_value(), line_info); return this->m_base.value(); } @@ -101,11 +228,6 @@ namespace vcpkg typename std::add_pointer::type get() { return this->m_base.has_value() ? &this->m_base.value() : nullptr; } private: - void exit_if_null(const LineInfo& line_info) const - { - Checks::check_exit(line_info, this->m_base.has_value(), "Value was null"); - } - details::OptionalStorage m_base; }; diff --git a/toolsrc/include/vcpkg/base/span.h b/toolsrc/include/vcpkg/base/span.h index 2b067d0ac..4c805e2b4 100644 --- a/toolsrc/include/vcpkg/base/span.h +++ b/toolsrc/include/vcpkg/base/span.h @@ -11,8 +11,9 @@ namespace vcpkg struct Span { public: - static_assert(!std::is_reference::value, "Span<&> is illegal"); + static_assert(std::is_object::value, "Span is illegal"); + using value_type = std::decay_t; using element_type = T; using pointer = std::add_pointer_t; using reference = std::add_lvalue_reference_t; @@ -30,46 +31,28 @@ namespace vcpkg } template - constexpr Span(const std::array, N>& arr) noexcept - : m_ptr(arr.data()), m_count(arr.size()) + constexpr Span(std::remove_const_t (&arr)[N]) noexcept : m_ptr(arr), m_count(N) { } - Span(std::vector& v) noexcept : Span(v.data(), v.size()) {} - Span(const std::vector>& v) noexcept : Span(v.data(), v.size()) {} + template().data()), + class = std::enable_if_t, Span>::value>> + constexpr Span(Range&& v) noexcept : Span(v.data(), v.size()) + { + static_assert(std::is_same::value_type, value_type>::value, + "Cannot convert incompatible ranges"); + } constexpr iterator begin() const { return m_ptr; } constexpr iterator end() const { return m_ptr + m_count; } constexpr reference operator[](size_t i) const { return m_ptr[i]; } + constexpr pointer data() const { return m_ptr; } constexpr size_t size() const { return m_count; } private: pointer m_ptr; size_t m_count; }; - - template - Span make_span(std::vector& v) - { - return {v.data(), v.size()}; - } - - template - Span make_span(const std::vector& v) - { - return {v.data(), v.size()}; - } - - template - constexpr T* begin(Span sp) - { - return sp.begin(); - } - - template - constexpr T* end(Span sp) - { - return sp.end(); - } } diff --git a/toolsrc/include/vcpkg/base/stringliteral.h b/toolsrc/include/vcpkg/base/stringliteral.h index 9970adc2a..602e0bfd2 100644 --- a/toolsrc/include/vcpkg/base/stringliteral.h +++ b/toolsrc/include/vcpkg/base/stringliteral.h @@ -1,27 +1,17 @@ #pragma once -#include +#include +#include namespace vcpkg { - struct StringLiteral + struct StringLiteral : ZStringView { template - constexpr StringLiteral(const char (&str)[N]) - : m_size(N - 1) /* -1 here accounts for the null byte at the end*/, m_cstr(str) + constexpr StringLiteral(const char (&str)[N]) : ZStringView(str) { } - constexpr const char* c_str() const { return m_cstr; } - constexpr size_t size() const { return m_size; } - - operator CStringView() const { return m_cstr; } - operator std::string() const { return m_cstr; } - - private: - size_t m_size; - const char* m_cstr; + operator std::string() const { return std::string(data(), size()); } }; - - inline const char* to_printf_arg(const StringLiteral str) { return str.c_str(); } } diff --git a/toolsrc/include/vcpkg/base/stringrange.h b/toolsrc/include/vcpkg/base/stringrange.h deleted file mode 100644 index 6126ec48f..000000000 --- a/toolsrc/include/vcpkg/base/stringrange.h +++ /dev/null @@ -1,33 +0,0 @@ -#pragma once - -#include - -#include -#include - -namespace vcpkg -{ - struct StringRange - { - static std::vector find_all_enclosed(const StringRange& input, - const std::string& left_delim, - const std::string& right_delim); - - static StringRange find_exactly_one_enclosed(const StringRange& input, - const std::string& left_tag, - const std::string& right_tag); - - static Optional find_at_most_one_enclosed(const StringRange& input, - const std::string& left_tag, - const std::string& right_tag); - - StringRange() = default; - StringRange(const std::string& s); // Implicit by design - StringRange(const std::string::const_iterator begin, const std::string::const_iterator end); - - std::string::const_iterator begin; - std::string::const_iterator end; - - std::string to_string() const; - }; -} diff --git a/toolsrc/include/vcpkg/base/strings.h b/toolsrc/include/vcpkg/base/strings.h index 4b39b0a28..16876cf5c 100644 --- a/toolsrc/include/vcpkg/base/strings.h +++ b/toolsrc/include/vcpkg/base/strings.h @@ -1,7 +1,10 @@ #pragma once #include +#include #include +#include +#include #include @@ -24,10 +27,63 @@ namespace vcpkg::Strings::details } std::string format_internal(const char* fmtstr, ...); + + inline void append_internal(std::string& into, char c) { into += c; } + template()))> + inline void append_internal(std::string& into, T x) + { + into += std::to_string(x); + } + inline void append_internal(std::string& into, const char* v) { into.append(v); } + inline void append_internal(std::string& into, const std::string& s) { into.append(s); } + + template().to_string(std::declval()))> + void append_internal(std::string& into, const T& t) + { + t.to_string(into); + } + + template(), std::declval()))> + void append_internal(std::string& into, const T& t) + { + to_string(into, t); + } } namespace vcpkg::Strings { + template + std::string& append(std::string& into, const Arg& a) + { + details::append_internal(into, a); + return into; + } + template + std::string& append(std::string& into, const Arg& a, const Args&... args) + { + append(into, a); + return append(into, args...); + } + + template + [[nodiscard]] std::string concat(const Args&... args) { + std::string ret; + append(ret, args...); + return ret; + } + + template + std::string concat_or_view(const Args&... args) + { + return Strings::concat(args...); + } + + template::value>> + StringView concat_or_view(const T& v) + { + return v; + } + template std::string format(const char* fmtstr, const Args&... args) { @@ -36,25 +92,25 @@ namespace vcpkg::Strings } #if defined(_WIN32) - std::wstring to_utf16(const CStringView& s); + std::wstring to_utf16(StringView s); std::string to_utf8(const wchar_t* w); + inline std::string to_utf8(const std::wstring& ws) { return to_utf8(ws.c_str()); } #endif - std::string escape_string(const CStringView& s, char char_to_escape, char escape_char); + std::string escape_string(std::string&& s, char char_to_escape, char escape_char); - std::string::const_iterator case_insensitive_ascii_find(const std::string& s, const std::string& pattern); + bool case_insensitive_ascii_contains(StringView s, StringView pattern); - bool case_insensitive_ascii_contains(const std::string& s, const std::string& pattern); + bool case_insensitive_ascii_equals(StringView left, StringView right); - bool case_insensitive_ascii_equals(const CStringView left, const CStringView right); + std::string ascii_to_lowercase(std::string&& s); - std::string ascii_to_lowercase(std::string s); + std::string ascii_to_uppercase(std::string&& s); - std::string ascii_to_uppercase(std::string s); - - bool case_insensitive_ascii_starts_with(const std::string& s, const std::string& pattern); - bool ends_with(const std::string& s, StringLiteral pattern); + bool case_insensitive_ascii_starts_with(StringView s, StringView pattern); + bool ends_with(StringView s, StringView pattern); + bool starts_with(StringView s, StringView pattern); template std::string join(const char* delimiter, const Container& v, Transformer transformer) @@ -84,7 +140,7 @@ namespace vcpkg::Strings return join(delimiter, v, [](const Element& x) -> const Element& { return x; }); } - std::string replace_all(std::string&& s, const std::string& search, const std::string& rep); + std::string replace_all(std::string&& s, const std::string& search, StringView rep); std::string trim(std::string&& s); @@ -92,6 +148,16 @@ namespace vcpkg::Strings std::vector split(const std::string& s, const std::string& delimiter); + std::vector split(const std::string& s, const std::string& delimiter, int max_count); + + std::vector find_all_enclosed(StringView input, StringView left_delim, StringView right_delim); + + StringView find_exactly_one_enclosed(StringView input, StringView left_tag, StringView right_tag); + + Optional find_at_most_one_enclosed(StringView input, StringView left_tag, StringView right_tag); + + bool equals(StringView a, StringView b); + template std::string serialize(const T& t) { @@ -99,4 +165,8 @@ namespace vcpkg::Strings serialize(t, ret); return ret; } + + const char* search(StringView haystack, StringView needle); + + bool contains(StringView haystack, StringView needle); } diff --git a/toolsrc/include/vcpkg/base/stringview.h b/toolsrc/include/vcpkg/base/stringview.h new file mode 100644 index 000000000..fef5bef4e --- /dev/null +++ b/toolsrc/include/vcpkg/base/stringview.h @@ -0,0 +1,49 @@ +#pragma once + +#include + +#include +#include + +namespace vcpkg +{ + struct StringView + { + static std::vector find_all_enclosed(const StringView& input, + const std::string& left_delim, + const std::string& right_delim); + + static StringView find_exactly_one_enclosed(const StringView& input, + const std::string& left_tag, + const std::string& right_tag); + + static Optional find_at_most_one_enclosed(const StringView& input, + const std::string& left_tag, + const std::string& right_tag); + + constexpr StringView() = default; + StringView(const std::string& s); // Implicit by design + template + StringView(const char (&arr)[Sz]) : m_ptr(arr), m_size(Sz - 1) + { + } + + constexpr StringView(const char* ptr, size_t size) : m_ptr(ptr), m_size(size) {} + constexpr StringView(const char* b, const char* e) : m_ptr(b), m_size(static_cast(e - b)) {} + + constexpr const char* begin() const { return m_ptr; } + constexpr const char* end() const { return m_ptr + m_size; } + + constexpr const char* data() const { return m_ptr; } + constexpr size_t size() const { return m_size; } + + std::string to_string() const; + void to_string(std::string& out) const; + + bool operator==(StringView other) const; + + private: + const char* m_ptr = 0; + size_t m_size = 0; + }; +} diff --git a/toolsrc/include/vcpkg/base/system.debug.h b/toolsrc/include/vcpkg/base/system.debug.h new file mode 100644 index 000000000..d9c50ac8e --- /dev/null +++ b/toolsrc/include/vcpkg/base/system.debug.h @@ -0,0 +1,50 @@ +#pragma once + +#include +#include + +#include + +namespace vcpkg::Debug +{ + extern std::atomic g_debugging; + + template + void print(System::Color c, const Args&... args) + { + if (g_debugging) System::print2(c, "[DEBUG] ", args...); + } + + template + void print(const Args&... args) + { + if (g_debugging) System::print2("[DEBUG] ", args...); + } + + template, class = std::enable_if_t::value>> + R time(LineInfo line, F&& f) + { + if (g_debugging) + { + auto timer = Chrono::ElapsedTimer::create_started(); + auto&& result = f(); + System::print2("[DEBUG] ", line, " took ", timer, '\n'); + return static_cast(result); + } + else + return f(); + } + + template, class = std::enable_if_t::value>> + void time(LineInfo line, F&& f) + { + if (g_debugging) + { + auto timer = Chrono::ElapsedTimer::create_started(); + f(); + System::print2("[DEBUG] ", line, " took ", timer, '\n'); + } + else + f(); + } +} diff --git a/toolsrc/include/vcpkg/base/system.h b/toolsrc/include/vcpkg/base/system.h index af56e45c1..0245b684a 100644 --- a/toolsrc/include/vcpkg/base/system.h +++ b/toolsrc/include/vcpkg/base/system.h @@ -1,85 +1,15 @@ #pragma once -#include - #include #include -#include +#include +#include namespace vcpkg::System { - fs::path get_exe_path_of_current_process(); + Optional get_environment_variable(ZStringView varname) noexcept; - struct CMakeVariable - { - CMakeVariable(const CStringView varname, const char* varvalue); - CMakeVariable(const CStringView varname, const std::string& varvalue); - CMakeVariable(const CStringView varname, const fs::path& path); - - std::string s; - }; - - std::string make_cmake_cmd(const fs::path& cmake_exe, - const fs::path& cmake_script, - const std::vector& pass_variables); - - struct ExitCodeAndOutput - { - int exit_code; - std::string output; - }; - - int cmd_execute_clean(const CStringView cmd_line, - const std::unordered_map& extra_env = {}) noexcept; - - int cmd_execute(const CStringView cmd_line) noexcept; - -#if defined(_WIN32) - void cmd_execute_no_wait(const CStringView cmd_line) noexcept; -#endif - - ExitCodeAndOutput cmd_execute_and_capture_output(const CStringView cmd_line) noexcept; - - enum class Color - { - success = 10, - error = 12, - warning = 14, - }; - - void println(); - void print(const CStringView message); - void println(const CStringView message); - void print(const Color c, const CStringView message); - void println(const Color c, const CStringView message); - - template - void print(const char* message_template, const Arg1& message_arg1, const Args&... message_args) - { - return System::print(Strings::format(message_template, message_arg1, message_args...)); - } - - template - void print(const Color c, const char* message_template, const Arg1& message_arg1, const Args&... message_args) - { - return System::print(c, Strings::format(message_template, message_arg1, message_args...)); - } - - template - void println(const char* message_template, const Arg1& message_arg1, const Args&... message_args) - { - return System::println(Strings::format(message_template, message_arg1, message_args...)); - } - - template - void println(const Color c, const char* message_template, const Arg1& message_arg1, const Args&... message_args) - { - return System::println(c, Strings::format(message_template, message_arg1, message_args...)); - } - - Optional get_environment_variable(const CStringView varname) noexcept; - - Optional get_registry_string(void* base_hkey, const CStringView subkey, const CStringView valuename); + Optional get_registry_string(void* base_hkey, StringView subkey, StringView valuename); enum class CPUArchitecture { @@ -89,7 +19,7 @@ namespace vcpkg::System ARM64, }; - Optional to_cpu_architecture(const CStringView& arch); + Optional to_cpu_architecture(StringView arch); CPUArchitecture get_host_processor(); @@ -99,24 +29,3 @@ namespace vcpkg::System const Optional& get_program_files_platform_bitness(); } - -namespace vcpkg::Debug -{ - void println(const CStringView message); - void println(const System::Color c, const CStringView message); - - template - void println(const char* message_template, const Arg1& message_arg1, const Args&... message_args) - { - return Debug::println(Strings::format(message_template, message_arg1, message_args...)); - } - - template - void println(const System::Color c, - const char* message_template, - const Arg1& message_arg1, - const Args&... message_args) - { - return Debug::println(c, Strings::format(message_template, message_arg1, message_args...)); - } -} diff --git a/toolsrc/include/vcpkg/base/system.print.h b/toolsrc/include/vcpkg/base/system.print.h new file mode 100644 index 000000000..890c13667 --- /dev/null +++ b/toolsrc/include/vcpkg/base/system.print.h @@ -0,0 +1,44 @@ +#pragma once + +#include +#include + +namespace vcpkg::System +{ + enum class Color + { + success = 10, + error = 12, + warning = 14, + }; + + namespace details + { + void print(StringView message); + void print(const Color c, StringView message); + } + + template + void printf(const char* message_template, const Arg1& message_arg1, const Args&... message_args) + { + return ::vcpkg::System::details::print(Strings::format(message_template, message_arg1, message_args...)); + } + + template + void printf(const Color c, const char* message_template, const Arg1& message_arg1, const Args&... message_args) + { + return ::vcpkg::System::details::print(c, Strings::format(message_template, message_arg1, message_args...)); + } + + template + void print2(const Color c, const Args&... args) + { + ::vcpkg::System::details::print(c, Strings::concat_or_view(args...)); + } + + template + void print2(const Args&... args) + { + ::vcpkg::System::details::print(Strings::concat_or_view(args...)); + } +} diff --git a/toolsrc/include/vcpkg/base/system.process.h b/toolsrc/include/vcpkg/base/system.process.h new file mode 100644 index 000000000..e409ff950 --- /dev/null +++ b/toolsrc/include/vcpkg/base/system.process.h @@ -0,0 +1,45 @@ +#pragma once + +#include +#include + +#include +#include +#include + +namespace vcpkg::System +{ + struct CMakeVariable + { + CMakeVariable(const StringView varname, const char* varvalue); + CMakeVariable(const StringView varname, const std::string& varvalue); + CMakeVariable(const StringView varname, const fs::path& path); + + std::string s; + }; + + std::string make_cmake_cmd(const fs::path& cmake_exe, + const fs::path& cmake_script, + const std::vector& pass_variables); + + fs::path get_exe_path_of_current_process(); + + struct ExitCodeAndOutput + { + int exit_code; + std::string output; + }; + + int cmd_execute_clean(const ZStringView cmd_line, + const std::unordered_map& extra_env = {}); + + int cmd_execute(const ZStringView cmd_line); + +#if defined(_WIN32) + void cmd_execute_no_wait(const StringView cmd_line); +#endif + + ExitCodeAndOutput cmd_execute_and_capture_output(const ZStringView cmd_line); + + void register_console_ctrl_handler(); +} diff --git a/toolsrc/include/vcpkg/base/util.h b/toolsrc/include/vcpkg/base/util.h index 65ce02b99..213adb67c 100644 --- a/toolsrc/include/vcpkg/base/util.h +++ b/toolsrc/include/vcpkg/base/util.h @@ -10,7 +10,8 @@ namespace vcpkg::Util { template - using ElementT = std::remove_reference_t()))>; + using ElementT = + std::remove_reference_t::iterator>())>; namespace Vectors { @@ -41,11 +42,11 @@ namespace vcpkg::Util } } - template - using FmapOut = decltype(std::declval()(*begin(std::declval()))); + template + using FmapOut = std::remove_reference_t()(*std::declval().begin()))>; - template> - std::vector fmap(Cont&& xs, Func&& f) + template> + std::vector fmap(Range&& xs, Func&& f) { std::vector ret; ret.reserve(xs.size()); @@ -93,12 +94,6 @@ namespace vcpkg::Util return std::find_if(begin(cont), end(cont), pred); } - template> - std::vector element_pointers(Container&& cont) - { - return fmap(cont, [](auto&& x) { return &x; }); - } - template auto find_if_not(Container&& cont, Pred pred) { diff --git a/toolsrc/include/vcpkg/base/view.h b/toolsrc/include/vcpkg/base/view.h new file mode 100644 index 000000000..8a9c40994 --- /dev/null +++ b/toolsrc/include/vcpkg/base/view.h @@ -0,0 +1,9 @@ +#pragma once + +#include + +namespace vcpkg +{ + template + using View = Span; +} diff --git a/toolsrc/include/vcpkg/base/zstringview.h b/toolsrc/include/vcpkg/base/zstringview.h new file mode 100644 index 000000000..7f80bf726 --- /dev/null +++ b/toolsrc/include/vcpkg/base/zstringview.h @@ -0,0 +1,52 @@ +#pragma once + +#include +#include +#include +#include + +#include + +namespace vcpkg +{ + // A counted view of a null-terminated string + struct ZStringView + { + using value_type = char; + + constexpr ZStringView() : m_size(0), m_cstr("") {} + + template + constexpr ZStringView(const char (&str)[N]) + : m_size(N - 1) /* -1 here accounts for the null byte at the end*/, m_cstr(str) + { + } + + ZStringView(const std::string& s) : m_size(s.size()), m_cstr(s.c_str()) {} + constexpr ZStringView(const char* str, size_t sz) : m_size(sz), m_cstr(str) {} + + constexpr const char* data() const { return m_cstr; } + constexpr size_t size() const { return m_size; } + constexpr char operator[](ptrdiff_t off) const { return m_cstr[off]; } + + constexpr const char* c_str() const { return m_cstr; } + + constexpr const char* begin() const { return m_cstr; } + constexpr const char* end() const { return m_cstr + m_size; } + + std::string to_string() const { return std::string(m_cstr, m_size); } + void to_string(std::string& out) const { out.append(m_cstr, m_size); } + + constexpr operator StringView() const { return StringView(m_cstr, m_size); } + + private: + size_t m_size; + const char* m_cstr; + }; + + inline bool operator==(ZStringView l, ZStringView r) { return std::equal(l.begin(), l.end(), r.begin(), r.end()); } + inline bool operator!=(ZStringView l, ZStringView r) { return !std::equal(l.begin(), l.end(), r.begin(), r.end()); } + + inline bool operator==(const char* l, ZStringView r) { return strcmp(l, r.c_str()) == 0; } + inline bool operator==(ZStringView l, const char* r) { return strcmp(l.c_str(), r) == 0; } +} diff --git a/toolsrc/include/vcpkg/globalstate.h b/toolsrc/include/vcpkg/globalstate.h index ae66ca355..2026ea369 100644 --- a/toolsrc/include/vcpkg/globalstate.h +++ b/toolsrc/include/vcpkg/globalstate.h @@ -4,6 +4,7 @@ #include #include +#include namespace vcpkg { @@ -19,26 +20,5 @@ namespace vcpkg static std::atomic g_init_console_cp; static std::atomic g_init_console_output_cp; static std::atomic g_init_console_initialized; - - struct CtrlCStateMachine - { - CtrlCStateMachine(); - - void transition_to_spawn_process() noexcept; - void transition_from_spawn_process() noexcept; - void transition_handle_ctrl_c() noexcept; - - private: - enum class CtrlCState - { - normal, - blocked_on_child, - exit_requested, - }; - - std::atomic m_state; - }; - - static CtrlCStateMachine g_ctrl_c_state; }; } diff --git a/toolsrc/include/vcpkg/input.h b/toolsrc/include/vcpkg/input.h index 621139427..ef481bf52 100644 --- a/toolsrc/include/vcpkg/input.h +++ b/toolsrc/include/vcpkg/input.h @@ -4,10 +4,10 @@ namespace vcpkg::Input { - PackageSpec check_and_get_package_spec(const std::string& package_spec_as_string, + PackageSpec check_and_get_package_spec(std::string&& spec_string, const Triplet& default_triplet, CStringView example_text); - FullPackageSpec check_and_get_full_package_spec(const std::string& full_package_spec_as_string, + FullPackageSpec check_and_get_full_package_spec(std::string&& spec_string, const Triplet& default_triplet, CStringView example_text); diff --git a/toolsrc/include/vcpkg/packagespec.h b/toolsrc/include/vcpkg/packagespec.h index 299a9c401..c87c6a2c6 100644 --- a/toolsrc/include/vcpkg/packagespec.h +++ b/toolsrc/include/vcpkg/packagespec.h @@ -35,6 +35,7 @@ namespace vcpkg std::string dir() const; std::string to_string() const; + void to_string(std::string& s) const; bool operator<(const PackageSpec& other) const { @@ -65,6 +66,7 @@ namespace vcpkg const PackageSpec& spec() const { return m_spec; } std::string to_string() const; + void to_string(std::string& out) const; static std::vector from_strings_and_triplet(const std::vector& depends, const Triplet& t); diff --git a/toolsrc/include/vcpkg/packagespecparseresult.h b/toolsrc/include/vcpkg/packagespecparseresult.h index be3497152..4c99c84c7 100644 --- a/toolsrc/include/vcpkg/packagespecparseresult.h +++ b/toolsrc/include/vcpkg/packagespecparseresult.h @@ -12,6 +12,8 @@ namespace vcpkg INVALID_CHARACTERS }; + void to_string(std::string& out, ::vcpkg::PackageSpecParseResult p); + CStringView to_string(PackageSpecParseResult ev) noexcept; template<> diff --git a/toolsrc/include/vcpkg/triplet.h b/toolsrc/include/vcpkg/triplet.h index 334960e49..f33f40fd5 100644 --- a/toolsrc/include/vcpkg/triplet.h +++ b/toolsrc/include/vcpkg/triplet.h @@ -11,7 +11,7 @@ namespace vcpkg public: constexpr Triplet() noexcept : m_instance(&DEFAULT_INSTANCE) {} - static Triplet from_canonical_name(const std::string& triplet_as_string); + static Triplet from_canonical_name(std::string&& triplet_as_string); static const Triplet X86_WINDOWS; static const Triplet X64_WINDOWS; @@ -24,6 +24,7 @@ namespace vcpkg const std::string& canonical_name() const; const std::string& to_string() const; + void to_string(std::string& out) const; size_t hash_code() const; bool operator==(const Triplet& other) const; diff --git a/toolsrc/src/vcpkg.cpp b/toolsrc/src/vcpkg.cpp index 97565bf41..f8b883e97 100644 --- a/toolsrc/src/vcpkg.cpp +++ b/toolsrc/src/vcpkg.cpp @@ -1,3 +1,13 @@ +#if defined(_MSC_VER) && _MSC_VER < 1911 +// [[nodiscard]] is not recognized before VS 2017 version 15.3 +#pragma warning(disable : 5030) +#endif + +#if defined(__GNUC__) && __GNUC__ < 7 +// [[nodiscard]] is not recognized before GCC version 7 +#pragma GCC diagnostic ignored "-Wattributes" +#endif + #if defined(_WIN32) #define WIN32_LEAN_AND_MEAN #include @@ -13,7 +23,9 @@ #include #include #include -#include +#include +#include +#include #include #include #include @@ -41,7 +53,7 @@ static constexpr int SURVEY_INITIAL_OFFSET_IN_HOURS = SURVEY_INTERVAL_IN_HOURS - void invalid_command(const std::string& cmd) { - System::println(System::Color::error, "invalid command: %s", cmd); + System::print2(System::Color::error, "invalid command: ", cmd, '\n'); Help::print_usage(); Checks::exit_fail(VCPKG_LINE_INFO); } @@ -100,7 +112,7 @@ static void inner(const VcpkgCmdArguments& args) Checks::check_exit(VCPKG_LINE_INFO, !vcpkg_root_dir.empty(), "Error: Could not detect vcpkg-root."); - Debug::println("Using vcpkg-root: %s", vcpkg_root_dir.u8string()); + Debug::print("Using vcpkg-root: ", vcpkg_root_dir.u8string(), '\n'); auto default_vs_path = System::get_environment_variable("VCPKG_VISUAL_STUDIO_PATH").value_or(""); @@ -137,10 +149,10 @@ static void inner(const VcpkgCmdArguments& args) if (distribution(generator) == 1) { Metrics::g_metrics.lock()->track_property("surveyprompt", "true"); - System::println( + System::print2( System::Color::success, "Your feedback is important to improve Vcpkg! Please take 3 minutes to complete our survey " - "by running: vcpkg contact --survey"); + "by running: vcpkg contact --survey\n"); } } } @@ -154,14 +166,14 @@ static void inner(const VcpkgCmdArguments& args) Triplet default_triplet; if (args.triplet != nullptr) { - default_triplet = Triplet::from_canonical_name(*args.triplet); + default_triplet = Triplet::from_canonical_name(std::string(*args.triplet)); } else { - const auto vcpkg_default_triplet_env = System::get_environment_variable("VCPKG_DEFAULT_TRIPLET"); - if (const auto v = vcpkg_default_triplet_env.get()) + auto vcpkg_default_triplet_env = System::get_environment_variable("VCPKG_DEFAULT_TRIPLET"); + if (auto v = vcpkg_default_triplet_env.get()) { - default_triplet = Triplet::from_canonical_name(*v); + default_triplet = Triplet::from_canonical_name(std::move(*v)); } else { @@ -279,6 +291,31 @@ int main(const int argc, const char* const* const argv) const std::string trimmed_command_line = trim_path_from_command_line(Strings::to_utf8(GetCommandLineW())); #endif + Checks::register_global_shutdown_handler([]() { + const auto elapsed_us_inner = GlobalState::timer.lock()->microseconds(); + + bool debugging = GlobalState::debugging; + + auto metrics = Metrics::g_metrics.lock(); + metrics->track_metric("elapsed_us", elapsed_us_inner); + GlobalState::debugging = false; + metrics->flush(); + +#if defined(_WIN32) + if (GlobalState::g_init_console_initialized) + { + SetConsoleCP(GlobalState::g_init_console_cp); + SetConsoleOutputCP(GlobalState::g_init_console_output_cp); + } +#endif + + auto elapsed_us = GlobalState::timer.lock()->microseconds(); + if (debugging) + System::printf("[DEBUG] Exiting after %d us (%d us)\n", + static_cast(elapsed_us), + static_cast(elapsed_us_inner)); + }); + { auto locked_metrics = Metrics::g_metrics.lock(); locked_metrics->track_property("version", Commands::Version::version()); @@ -287,7 +324,7 @@ int main(const int argc, const char* const* const argv) #endif } - Checks::register_console_ctrl_handler(); + System::register_console_ctrl_handler(); load_config(); @@ -330,24 +367,24 @@ int main(const int argc, const char* const* const argv) Metrics::g_metrics.lock()->track_property("error", exc_msg); fflush(stdout); - System::print("vcpkg.exe has crashed.\n" - "Please send an email to:\n" - " %s\n" - "containing a brief summary of what you were trying to do and the following data blob:\n" - "\n" - "Version=%s\n" - "EXCEPTION='%s'\n" - "CMD=\n", - Commands::Contact::email(), - Commands::Version::version(), - exc_msg); + System::printf("vcpkg.exe has crashed.\n" + "Please send an email to:\n" + " %s\n" + "containing a brief summary of what you were trying to do and the following data blob:\n" + "\n" + "Version=%s\n" + "EXCEPTION='%s'\n" + "CMD=\n", + Commands::Contact::email(), + Commands::Version::version(), + exc_msg); fflush(stdout); for (int x = 0; x < argc; ++x) { #if defined(_WIN32) - System::println("%s|", Strings::to_utf8(argv[x])); + System::print2(Strings::to_utf8(argv[x]), "|\n"); #else - System::println("%s|", argv[x]); + System::print2(argv[x], "|\n"); #endif } fflush(stdout); diff --git a/toolsrc/src/vcpkg/archives.cpp b/toolsrc/src/vcpkg/archives.cpp index 38efedf87..037cbdc14 100644 --- a/toolsrc/src/vcpkg/archives.cpp +++ b/toolsrc/src/vcpkg/archives.cpp @@ -2,6 +2,7 @@ #include #include +#include namespace vcpkg::Archives { diff --git a/toolsrc/src/vcpkg/base/checks.cpp b/toolsrc/src/vcpkg/base/checks.cpp index cc439adfe..0266ad683 100644 --- a/toolsrc/src/vcpkg/base/checks.cpp +++ b/toolsrc/src/vcpkg/base/checks.cpp @@ -1,41 +1,27 @@ #include "pch.h" -#include -#include - #include -#include +#include +#include -namespace vcpkg::Checks +namespace vcpkg { + static void (*g_shutdown_handler)() = nullptr; + void Checks::register_global_shutdown_handler(void (*func)()) + { + if (g_shutdown_handler) + // Setting the handler twice is a program error. Terminate. + std::abort(); + g_shutdown_handler = func; + } + [[noreturn]] static void cleanup_and_exit(const int exit_code) { static std::atomic have_entered{false}; if (have_entered) std::terminate(); have_entered = true; - const auto elapsed_us_inner = GlobalState::timer.lock()->microseconds(); - - bool debugging = GlobalState::debugging; - - auto metrics = Metrics::g_metrics.lock(); - metrics->track_metric("elapsed_us", elapsed_us_inner); - GlobalState::debugging = false; - metrics->flush(); - -#if defined(_WIN32) - if (GlobalState::g_init_console_initialized) - { - SetConsoleCP(GlobalState::g_init_console_cp); - SetConsoleOutputCP(GlobalState::g_init_console_output_cp); - } -#endif - - auto elapsed_us = GlobalState::timer.lock()->microseconds(); - if (debugging) - System::println("[DEBUG] Exiting after %d us (%d us)", - static_cast(elapsed_us), - static_cast(elapsed_us_inner)); + if (g_shutdown_handler) g_shutdown_handler(); fflush(nullptr); @@ -46,27 +32,10 @@ namespace vcpkg::Checks #endif } -#if defined(_WIN32) - static BOOL ctrl_handler(DWORD fdw_ctrl_type) + void Checks::unreachable(const LineInfo& line_info) { - switch (fdw_ctrl_type) - { - case CTRL_C_EVENT: GlobalState::g_ctrl_c_state.transition_handle_ctrl_c(); return TRUE; - default: return FALSE; - } - } - - void register_console_ctrl_handler() - { - SetConsoleCtrlHandler(reinterpret_cast(ctrl_handler), TRUE); - } -#else - void register_console_ctrl_handler() {} -#endif - void unreachable(const LineInfo& line_info) - { - System::println(System::Color::error, "Error: Unreachable code was reached"); - System::println(System::Color::error, line_info.to_string()); // Always print line_info here + System::print2(System::Color::error, "Error: Unreachable code was reached\n"); + System::print2(System::Color::error, line_info, '\n'); // Always print line_info here #ifndef NDEBUG std::abort(); #else @@ -74,19 +43,19 @@ namespace vcpkg::Checks #endif } - void exit_with_code(const LineInfo& line_info, const int exit_code) + void Checks::exit_with_code(const LineInfo& line_info, const int exit_code) { - Debug::println(System::Color::error, line_info.to_string()); + Debug::print(System::Color::error, line_info, '\n'); cleanup_and_exit(exit_code); } - void exit_with_message(const LineInfo& line_info, const CStringView error_message) + void Checks::exit_with_message(const LineInfo& line_info, StringView error_message) { - System::println(System::Color::error, error_message); + System::print2(System::Color::error, error_message, '\n'); exit_fail(line_info); } - void check_exit(const LineInfo& line_info, bool expression) + void Checks::check_exit(const LineInfo& line_info, bool expression) { if (!expression) { @@ -94,11 +63,27 @@ namespace vcpkg::Checks } } - void check_exit(const LineInfo& line_info, bool expression, const CStringView error_message) + void Checks::check_exit(const LineInfo& line_info, bool expression, StringView error_message) { if (!expression) { exit_with_message(line_info, error_message); } } + + std::string LineInfo::to_string() const + { + std::string ret; + this->to_string(ret); + return ret; + } + void LineInfo::to_string(std::string& out) const + { + out += m_file_name; + Strings::append(out, '(', m_line_number, ')'); + } + namespace details + { + void exit_if_null(bool b, const LineInfo& line_info) { Checks::check_exit(line_info, b, "Value was null"); } + } } diff --git a/toolsrc/src/vcpkg/base/chrono.cpp b/toolsrc/src/vcpkg/base/chrono.cpp index 405e76605..959ff90c8 100644 --- a/toolsrc/src/vcpkg/base/chrono.cpp +++ b/toolsrc/src/vcpkg/base/chrono.cpp @@ -113,8 +113,13 @@ namespace vcpkg::Chrono } std::string ElapsedTime::to_string() const { return format_time_userfriendly(as()); } + void ElapsedTime::to_string(std::string& into) const + { + into += format_time_userfriendly(as()); + } std::string ElapsedTimer::to_string() const { return elapsed().to_string(); } + void ElapsedTimer::to_string(std::string& into) const { return elapsed().to_string(into); } Optional CTime::get_current_date_time() { diff --git a/toolsrc/src/vcpkg/base/cofffilereader.cpp b/toolsrc/src/vcpkg/base/cofffilereader.cpp index 2c09e2c19..cb75e0847 100644 --- a/toolsrc/src/vcpkg/base/cofffilereader.cpp +++ b/toolsrc/src/vcpkg/base/cofffilereader.cpp @@ -33,11 +33,13 @@ namespace vcpkg::CoffFileReader return data; } - static void verify_equal_strings( - const LineInfo& line_info, const char* expected, const char* actual, int size, const char* label) + static void verify_equal_strings(const LineInfo& line_info, + StringView expected, + StringView actual, + const char* label) { Checks::check_exit(line_info, - memcmp(expected, actual, size) == 0, + expected == actual, "Incorrect string (%s) found. Expected: (%s) but found (%s)", label, expected, @@ -57,7 +59,7 @@ namespace vcpkg::CoffFileReader fs.seekg(offset_to_pe_signature); char signature[PE_SIGNATURE_SIZE]; fs.read(signature, PE_SIGNATURE_SIZE); - verify_equal_strings(VCPKG_LINE_INFO, PE_SIGNATURE.c_str(), signature, PE_SIGNATURE_SIZE, "PE_SIGNATURE"); + verify_equal_strings(VCPKG_LINE_INFO, PE_SIGNATURE, {signature, PE_SIGNATURE_SIZE}, "PE_SIGNATURE"); fs.seekg(offset_to_pe_signature + PE_SIGNATURE_SIZE, ios_base::beg); } @@ -113,8 +115,7 @@ namespace vcpkg::CoffFileReader if (ret.data[0] != '\0') // Due to freeglut. github issue #223 { const std::string header_end = ret.data.substr(HEADER_END_OFFSET, HEADER_END_SIZE); - verify_equal_strings( - VCPKG_LINE_INFO, HEADER_END.c_str(), header_end.c_str(), HEADER_END_SIZE, "LIB HEADER_END"); + verify_equal_strings(VCPKG_LINE_INFO, HEADER_END, header_end, "LIB HEADER_END"); } return ret; @@ -229,7 +230,7 @@ namespace vcpkg::CoffFileReader char file_start[FILE_START_SIZE]; fs.read(file_start, FILE_START_SIZE); - verify_equal_strings(VCPKG_LINE_INFO, FILE_START.c_str(), file_start, FILE_START_SIZE, "LIB FILE_START"); + verify_equal_strings(VCPKG_LINE_INFO, FILE_START, {file_start, FILE_START_SIZE}, "LIB FILE_START"); } DllInfo read_dll(const fs::path& path) diff --git a/toolsrc/src/vcpkg/base/downloads.cpp b/toolsrc/src/vcpkg/base/downloads.cpp index 571562244..590c48ff5 100644 --- a/toolsrc/src/vcpkg/base/downloads.cpp +++ b/toolsrc/src/vcpkg/base/downloads.cpp @@ -2,6 +2,7 @@ #include #include +#include #include #if defined(_WIN32) @@ -14,9 +15,9 @@ namespace vcpkg::Downloads { #if defined(_WIN32) static void winhttp_download_file(Files::Filesystem& fs, - CStringView target_file_path, - CStringView hostname, - CStringView url_path) + ZStringView target_file_path, + StringView hostname, + StringView url_path) { // Make sure the directories are present, otherwise fopen_s fails const auto dir = fs::path(target_file_path.c_str()).parent_path(); @@ -163,7 +164,7 @@ namespace vcpkg::Downloads std::string hostname(url_no_proto.begin(), path_begin); std::string path(path_begin, url_no_proto.end()); - winhttp_download_file(fs, download_path_part.c_str(), hostname, path); + winhttp_download_file(fs, download_path_part, hostname, path); #else const auto code = System::cmd_execute( Strings::format(R"(curl -L '%s' --create-dirs --output '%s')", url, download_path_part)); diff --git a/toolsrc/src/vcpkg/base/files.cpp b/toolsrc/src/vcpkg/base/files.cpp index 34a6489a8..164394100 100644 --- a/toolsrc/src/vcpkg/base/files.cpp +++ b/toolsrc/src/vcpkg/base/files.cpp @@ -1,7 +1,10 @@ #include "pch.h" #include +#include #include +#include +#include #include #if defined(__linux__) @@ -209,10 +212,11 @@ namespace vcpkg::Files if (this->exists(path)) { - System::println(System::Color::warning, - "Some files in %s were unable to be removed. Close any editors operating in this " - "directory and retry.", - path.string()); + System::print2( + System::Color::warning, + "Some files in ", + path.u8string(), + " were unable to be removed. Close any editors operating in this directory and retry.\n"); } return out; @@ -298,14 +302,14 @@ namespace vcpkg::Files if (Util::find(ret, p) == ret.end() && this->exists(p)) { ret.push_back(p); - Debug::println("Found path: %s", p.u8string()); + Debug::print("Found path: ", p.u8string(), '\n'); } } } return ret; #else - const std::string cmd = Strings::format("which %s", name); + const std::string cmd = Strings::concat("which ", name); auto out = System::cmd_execute_and_capture_output(cmd); if (out.exit_code != 0) { @@ -330,11 +334,12 @@ namespace vcpkg::Files void print_paths(const std::vector& paths) { - System::println(); + std::string message = "\n"; for (const fs::path& p : paths) { - System::println(" %s", p.generic_string()); + Strings::append(message, " ", p.generic_string(), '\n'); } - System::println(); + message.push_back('\n'); + System::print2(message); } } diff --git a/toolsrc/src/vcpkg/base/hash.cpp b/toolsrc/src/vcpkg/base/hash.cpp index 7a74371db..310b8c35e 100644 --- a/toolsrc/src/vcpkg/base/hash.cpp +++ b/toolsrc/src/vcpkg/base/hash.cpp @@ -2,11 +2,12 @@ #include #include -#include +#include #include #if defined(_WIN32) #include +#pragma comment(lib, "bcrypt") #ifndef NT_SUCCESS #define NT_SUCCESS(Status) (((NTSTATUS)(Status)) >= 0) @@ -94,13 +95,13 @@ namespace vcpkg::Hash } public: - explicit BCryptHasher(const std::string& hash_type) + explicit BCryptHasher(std::string hash_type) { - NTSTATUS error_code = - BCryptOpenAlgorithmProvider(&this->algorithm_handle.handle, - Strings::to_utf16(Strings::ascii_to_uppercase(hash_type)).c_str(), - nullptr, - 0); + NTSTATUS error_code = BCryptOpenAlgorithmProvider( + &this->algorithm_handle.handle, + Strings::to_utf16(Strings::ascii_to_uppercase(std::move(hash_type))).c_str(), + nullptr, + 0); Checks::check_exit(VCPKG_LINE_INFO, NT_SUCCESS(error_code), "Failed to open the algorithm provider"); DWORD hash_buffer_bytes; diff --git a/toolsrc/src/vcpkg/base/lineinfo.cpp b/toolsrc/src/vcpkg/base/lineinfo.cpp deleted file mode 100644 index 7435ed666..000000000 --- a/toolsrc/src/vcpkg/base/lineinfo.cpp +++ /dev/null @@ -1,9 +0,0 @@ -#include "pch.h" - -#include -#include - -namespace vcpkg -{ - std::string LineInfo::to_string() const { return Strings::format("%s(%d)", this->file_name, this->line_number); } -} diff --git a/toolsrc/src/vcpkg/base/stringrange.cpp b/toolsrc/src/vcpkg/base/stringrange.cpp deleted file mode 100644 index f7e431c88..000000000 --- a/toolsrc/src/vcpkg/base/stringrange.cpp +++ /dev/null @@ -1,79 +0,0 @@ -#include "pch.h" - -#include -#include - -namespace vcpkg -{ - std::vector StringRange::find_all_enclosed(const StringRange& input, - const std::string& left_delim, - const std::string& right_delim) - { - std::string::const_iterator it_left = input.begin; - std::string::const_iterator it_right = input.begin; - - std::vector output; - - while (true) - { - it_left = std::search(it_right, input.end, left_delim.cbegin(), left_delim.cend()); - if (it_left == input.end) break; - - it_left += left_delim.length(); - - it_right = std::search(it_left, input.end, right_delim.cbegin(), right_delim.cend()); - if (it_right == input.end) break; - - output.emplace_back(it_left, it_right); - - ++it_right; - } - - return output; - } - - StringRange StringRange::find_exactly_one_enclosed(const StringRange& input, - const std::string& left_tag, - const std::string& right_tag) - { - std::vector result = find_all_enclosed(input, left_tag, right_tag); - Checks::check_exit(VCPKG_LINE_INFO, - result.size() == 1, - "Found %d sets of %s.*%s but expected exactly 1, in block:\n%s", - result.size(), - left_tag, - right_tag, - input); - return result.front(); - } - - Optional StringRange::find_at_most_one_enclosed(const StringRange& input, - const std::string& left_tag, - const std::string& right_tag) - { - std::vector result = find_all_enclosed(input, left_tag, right_tag); - Checks::check_exit(VCPKG_LINE_INFO, - result.size() <= 1, - "Found %d sets of %s.*%s but expected at most 1, in block:\n%s", - result.size(), - left_tag, - right_tag, - input); - - if (result.empty()) - { - return nullopt; - } - - return result.front(); - } - - StringRange::StringRange(const std::string& s) : begin(s.cbegin()), end(s.cend()) {} - - StringRange::StringRange(const std::string::const_iterator begin, const std::string::const_iterator end) - : begin(begin), end(end) - { - } - - std::string StringRange::to_string() const { return std::string(this->begin, this->end); } -} diff --git a/toolsrc/src/vcpkg/base/strings.cpp b/toolsrc/src/vcpkg/base/strings.cpp index 8d43e7af7..ce634a227 100644 --- a/toolsrc/src/vcpkg/base/strings.cpp +++ b/toolsrc/src/vcpkg/base/strings.cpp @@ -10,8 +10,10 @@ namespace vcpkg::Strings::details static bool is_space(const char c) { return std::isspace(c) != 0; } // Avoids C4244 warnings because of char<->int conversion that occur when using std::tolower() - static char tolower_char(const char c) { return static_cast(std::tolower(c)); } - static char toupper_char(const char c) { return static_cast(std::toupper(c)); } + static char tolower_char(const char c) { return (c < 'A' || c > 'Z') ? c : c - 'A' + 'a'; } + static char toupper_char(const char c) { return (c < 'a' || c > 'z') ? c : c - 'a' + 'A'; } + + static bool icase_eq(char a, char b) { return tolower_char(a) == tolower_char(b); } #if defined(_WIN32) static _locale_t& c_locale() @@ -47,146 +49,242 @@ namespace vcpkg::Strings::details } } -namespace vcpkg::Strings +using namespace vcpkg; + +#if defined(_WIN32) +std::wstring Strings::to_utf16(StringView s) { -#if defined(_WIN32) - std::wstring to_utf16(const CStringView& s) - { - std::wstring output; - const size_t size = MultiByteToWideChar(CP_UTF8, 0, s.c_str(), -1, nullptr, 0); - if (size == 0) return output; - output.resize(size - 1); - MultiByteToWideChar(CP_UTF8, 0, s.c_str(), -1, output.data(), static_cast(size) - 1); - return output; - } -#endif - -#if defined(_WIN32) - std::string to_utf8(const wchar_t* w) - { - std::string output; - const size_t size = WideCharToMultiByte(CP_UTF8, 0, w, -1, nullptr, 0, nullptr, nullptr); - if (size == 0) return output; - output.resize(size - 1); - WideCharToMultiByte(CP_UTF8, 0, w, -1, output.data(), static_cast(size) - 1, nullptr, nullptr); - return output; - } -#endif - - std::string escape_string(const CStringView& s, char char_to_escape, char escape_char) - { - std::string ret = s.c_str(); - // Replace '\' with '\\' or '`' with '``' - ret = Strings::replace_all(std::move(ret), {escape_char}, {escape_char, escape_char}); - // Replace '"' with '\"' or '`"' - ret = Strings::replace_all(std::move(ret), {char_to_escape}, {escape_char, char_to_escape}); - return ret; - } - - std::string::const_iterator case_insensitive_ascii_find(const std::string& s, const std::string& pattern) - { - const std::string pattern_as_lower_case(ascii_to_lowercase(pattern)); - return search(s.begin(), - s.end(), - pattern_as_lower_case.begin(), - pattern_as_lower_case.end(), - [](const char a, const char b) { return details::tolower_char(a) == b; }); - } - - bool case_insensitive_ascii_contains(const std::string& s, const std::string& pattern) - { - return case_insensitive_ascii_find(s, pattern) != s.end(); - } - - bool case_insensitive_ascii_equals(const CStringView left, const CStringView right) - { -#if defined(_WIN32) - return _stricmp(left.c_str(), right.c_str()) == 0; -#else - return strcasecmp(left.c_str(), right.c_str()) == 0; -#endif - } - - std::string ascii_to_lowercase(std::string s) - { - std::transform(s.begin(), s.end(), s.begin(), &details::tolower_char); - return s; - } - - std::string ascii_to_uppercase(std::string s) - { - std::transform(s.begin(), s.end(), s.begin(), &details::toupper_char); - return s; - } - - bool case_insensitive_ascii_starts_with(const std::string& s, const std::string& pattern) - { -#if defined(_WIN32) - return _strnicmp(s.c_str(), pattern.c_str(), pattern.size()) == 0; -#else - return strncasecmp(s.c_str(), pattern.c_str(), pattern.size()) == 0; -#endif - } - - bool ends_with(const std::string& s, StringLiteral pattern) - { - if (s.size() < pattern.size()) return false; - return std::equal(s.end() - pattern.size(), s.end(), pattern.c_str(), pattern.c_str() + pattern.size()); - } - - std::string replace_all(std::string&& s, const std::string& search, const std::string& rep) - { - size_t pos = 0; - while ((pos = s.find(search, pos)) != std::string::npos) - { - s.replace(pos, search.size(), rep); - pos += rep.size(); - } - return std::move(s); - } - - std::string trim(std::string&& s) - { - s.erase(std::find_if_not(s.rbegin(), s.rend(), details::is_space).base(), s.end()); - s.erase(s.begin(), std::find_if_not(s.begin(), s.end(), details::is_space)); - return std::move(s); - } - - void trim_all_and_remove_whitespace_strings(std::vector* strings) - { - for (std::string& s : *strings) - { - s = trim(std::move(s)); - } - - Util::erase_remove_if(*strings, [](const std::string& s) { return s.empty(); }); - } - - std::vector split(const std::string& s, const std::string& delimiter) - { - std::vector output; - - if (delimiter.empty()) - { - output.push_back(s); - return output; - } - - const size_t delimiter_length = delimiter.length(); - size_t i = 0; - for (size_t pos = s.find(delimiter); pos != std::string::npos; pos = s.find(delimiter, pos)) - { - output.push_back(s.substr(i, pos - i)); - pos += delimiter_length; - i = pos; - } - - // Add the rest of the string after the last delimiter, unless there is nothing after it - if (i != s.length()) - { - output.push_back(s.substr(i, s.length())); - } - - return output; - } + std::wstring output; + if (s.size() == 0) return output; + Checks::check_exit(VCPKG_LINE_INFO, s.size() < size_t(INT_MAX)); + int size = MultiByteToWideChar(CP_UTF8, 0, s.data(), static_cast(s.size()), nullptr, 0); + output.resize(static_cast(size)); + MultiByteToWideChar(CP_UTF8, 0, s.data(), static_cast(s.size()), output.data(), size); + return output; +} +#endif + +#if defined(_WIN32) +std::string Strings::to_utf8(const wchar_t* w) +{ + std::string output; + const size_t size = WideCharToMultiByte(CP_UTF8, 0, w, -1, nullptr, 0, nullptr, nullptr); + if (size == 0) return output; + output.resize(size - 1); + WideCharToMultiByte(CP_UTF8, 0, w, -1, output.data(), static_cast(size) - 1, nullptr, nullptr); + return output; +} +#endif + +std::string Strings::escape_string(std::string&& s, char char_to_escape, char escape_char) +{ + // Replace '\' with '\\' or '`' with '``' + auto ret = Strings::replace_all(std::move(s), {&escape_char, 1}, std::string{escape_char, escape_char}); + // Replace '"' with '\"' or '`"' + ret = Strings::replace_all(std::move(ret), {&char_to_escape, 1}, std::string{escape_char, char_to_escape}); + return ret; +} + +static const char* case_insensitive_ascii_find(StringView s, StringView pattern) +{ + return std::search(s.begin(), s.end(), pattern.begin(), pattern.end(), &Strings::details::icase_eq); +} + +bool Strings::case_insensitive_ascii_contains(StringView s, StringView pattern) +{ + return case_insensitive_ascii_find(s, pattern) != s.end(); +} + +bool Strings::case_insensitive_ascii_equals(StringView left, StringView right) +{ + return std::equal(left.begin(), left.end(), right.begin(), right.end(), &details::icase_eq); +} + +std::string Strings::ascii_to_lowercase(std::string&& s) +{ + std::transform(s.begin(), s.end(), s.begin(), &details::tolower_char); + return std::move(s); +} + +std::string Strings::ascii_to_uppercase(std::string&& s) +{ + std::transform(s.begin(), s.end(), s.begin(), &details::toupper_char); + return std::move(s); +} + +bool Strings::case_insensitive_ascii_starts_with(StringView s, StringView pattern) +{ + if (s.size() < pattern.size()) return false; + return std::equal(s.begin(), s.begin() + pattern.size(), pattern.begin(), pattern.end(), &details::icase_eq); +} + +bool Strings::ends_with(StringView s, StringView pattern) +{ + if (s.size() < pattern.size()) return false; + return std::equal(s.end() - pattern.size(), s.end(), pattern.begin(), pattern.end()); +} +bool Strings::starts_with(StringView s, StringView pattern) +{ + if (s.size() < pattern.size()) return false; + return std::equal(s.begin(), s.begin() + pattern.size(), pattern.begin(), pattern.end()); +} + +std::string Strings::replace_all(std::string&& s, const std::string& search, StringView rep) +{ + size_t pos = 0; + while ((pos = s.find(search, pos)) != std::string::npos) + { + s.replace(pos, search.size(), rep.data(), rep.size()); + pos += rep.size(); + } + return std::move(s); +} + +std::string Strings::trim(std::string&& s) +{ + s.erase(std::find_if_not(s.rbegin(), s.rend(), details::is_space).base(), s.end()); + s.erase(s.begin(), std::find_if_not(s.begin(), s.end(), details::is_space)); + return std::move(s); +} + +void Strings::trim_all_and_remove_whitespace_strings(std::vector* strings) +{ + for (std::string& s : *strings) + { + s = trim(std::move(s)); + } + + Util::erase_remove_if(*strings, [](const std::string& s) { return s.empty(); }); +} + +std::vector Strings::split(const std::string& s, const std::string& delimiter) +{ + std::vector output; + + if (delimiter.empty()) + { + output.push_back(s); + return output; + } + + const size_t delimiter_length = delimiter.length(); + size_t i = 0; + for (size_t pos = s.find(delimiter); pos != std::string::npos; pos = s.find(delimiter, pos)) + { + output.push_back(s.substr(i, pos - i)); + pos += delimiter_length; + i = pos; + } + + // Add the rest of the string after the last delimiter, unless there is nothing after it + if (i != s.length()) + { + output.push_back(s.substr(i, s.length())); + } + + return output; +} + +std::vector Strings::split(const std::string& s, const std::string& delimiter, int max_count) +{ + std::vector output; + + Checks::check_exit(VCPKG_LINE_INFO, max_count >= 1); + + if (delimiter.empty()) + { + output.push_back(s); + return output; + } + + const size_t delimiter_length = delimiter.length(); + size_t i = 0; + for (size_t pos = s.find(delimiter); pos != std::string::npos; pos = s.find(delimiter, pos)) + { + if (output.size() == max_count - 1) break; + output.push_back(s.substr(i, pos - i)); + pos += delimiter_length; + i = pos; + } + + // Add the rest of the string after the last delimiter, unless there is nothing after it + if (i != s.length()) + { + output.push_back(s.substr(i, s.length())); + } + + return output; +} + +std::vector Strings::find_all_enclosed(StringView input, StringView left_delim, StringView right_delim) +{ + auto it_left = input.begin(); + auto it_right = input.begin(); + + std::vector output; + + while (true) + { + it_left = std::search(it_right, input.end(), left_delim.begin(), left_delim.end()); + if (it_left == input.end()) break; + + it_left += left_delim.size(); + + it_right = std::search(it_left, input.end(), right_delim.begin(), right_delim.end()); + if (it_right == input.end()) break; + + output.emplace_back(it_left, it_right); + + ++it_right; + } + + return output; +} + +StringView Strings::find_exactly_one_enclosed(StringView input, StringView left_tag, StringView right_tag) +{ + std::vector result = find_all_enclosed(input, left_tag, right_tag); + Checks::check_exit(VCPKG_LINE_INFO, + result.size() == 1, + "Found %d sets of %s.*%s but expected exactly 1, in block:\n%s", + result.size(), + left_tag, + right_tag, + input); + return result.front(); +} + +Optional Strings::find_at_most_one_enclosed(StringView input, StringView left_tag, StringView right_tag) +{ + std::vector result = find_all_enclosed(input, left_tag, right_tag); + Checks::check_exit(VCPKG_LINE_INFO, + result.size() <= 1, + "Found %d sets of %s.*%s but expected at most 1, in block:\n%s", + result.size(), + left_tag, + right_tag, + input); + + if (result.empty()) + { + return nullopt; + } + + return result.front(); +} + +bool Strings::equals(StringView a, StringView b) +{ + if (a.size() != b.size()) return false; + return std::equal(a.begin(), a.end(), b.begin(), b.end()); +} + +const char* Strings::search(StringView haystack, StringView needle) +{ + return std::search(haystack.begin(), haystack.end(), needle.begin(), needle.end()); +} + +bool Strings::contains(StringView haystack, StringView needle) +{ + return Strings::search(haystack, needle) != haystack.end(); } diff --git a/toolsrc/src/vcpkg/base/stringview.cpp b/toolsrc/src/vcpkg/base/stringview.cpp new file mode 100644 index 000000000..d0b2cd43a --- /dev/null +++ b/toolsrc/src/vcpkg/base/stringview.cpp @@ -0,0 +1,83 @@ +#include "pch.h" + +#include +#include +#include + +#include + +namespace vcpkg +{ + std::vector StringView::find_all_enclosed(const StringView& input, + const std::string& left_delim, + const std::string& right_delim) + { + auto it_left = input.begin(); + auto it_right = input.begin(); + + std::vector output; + + while (true) + { + it_left = std::search(it_right, input.end(), left_delim.cbegin(), left_delim.cend()); + if (it_left == input.end()) break; + + it_left += left_delim.length(); + + it_right = std::search(it_left, input.end(), right_delim.cbegin(), right_delim.cend()); + if (it_right == input.end()) break; + + output.emplace_back(it_left, it_right); + + ++it_right; + } + + return output; + } + + StringView StringView::find_exactly_one_enclosed(const StringView& input, + const std::string& left_tag, + const std::string& right_tag) + { + std::vector result = find_all_enclosed(input, left_tag, right_tag); + Checks::check_exit(VCPKG_LINE_INFO, + result.size() == 1, + "Found %d sets of %s.*%s but expected exactly 1, in block:\n%s", + result.size(), + left_tag, + right_tag, + input); + return result.front(); + } + + Optional StringView::find_at_most_one_enclosed(const StringView& input, + const std::string& left_tag, + const std::string& right_tag) + { + std::vector result = find_all_enclosed(input, left_tag, right_tag); + Checks::check_exit(VCPKG_LINE_INFO, + result.size() <= 1, + "Found %d sets of %s.*%s but expected at most 1, in block:\n%s", + result.size(), + left_tag, + right_tag, + input); + + if (result.empty()) + { + return nullopt; + } + + return result.front(); + } + + StringView::StringView(const std::string& s) : m_ptr(s.data()), m_size(s.size()) {} + + std::string StringView::to_string() const { return std::string(m_ptr, m_size); } + void StringView::to_string(std::string& s) const { s.append(m_ptr, m_size); } + + bool StringView::operator==(StringView other) const + { + return other.size() == size() && memcmp(data(), other.data(), size()) == 0; + } +} diff --git a/toolsrc/src/vcpkg/base/system.cpp b/toolsrc/src/vcpkg/base/system.cpp index 6ddf17496..ffbac3158 100644 --- a/toolsrc/src/vcpkg/base/system.cpp +++ b/toolsrc/src/vcpkg/base/system.cpp @@ -1,9 +1,10 @@ #include "pch.h" #include +#include +#include #include -#include -#include +#include #include @@ -17,9 +18,73 @@ #pragma comment(lib, "Advapi32") -namespace vcpkg::System +using namespace vcpkg::System; + +namespace vcpkg { - fs::path get_exe_path_of_current_process() +#if defined(_WIN32) + namespace + { + struct CtrlCStateMachine + { + CtrlCStateMachine() : m_state(CtrlCState::normal) {} + + void transition_to_spawn_process() noexcept + { + auto expected = CtrlCState::normal; + auto transitioned = m_state.compare_exchange_strong(expected, CtrlCState::blocked_on_child); + if (!transitioned) + { + // Ctrl-C was hit and is asynchronously executing on another thread + Checks::exit_fail(VCPKG_LINE_INFO); + } + } + void transition_from_spawn_process() noexcept + { + auto expected = CtrlCState::blocked_on_child; + auto transitioned = m_state.compare_exchange_strong(expected, CtrlCState::normal); + if (!transitioned) + { + // Ctrl-C was hit while blocked on the child process, so exit immediately + Checks::exit_fail(VCPKG_LINE_INFO); + } + } + void transition_handle_ctrl_c() noexcept + { + auto prev_state = m_state.exchange(CtrlCState::exit_requested); + + if (prev_state == CtrlCState::normal) + { + // Not currently blocked on a child process and Ctrl-C has not been hit. + Checks::exit_fail(VCPKG_LINE_INFO); + } + else if (prev_state == CtrlCState::exit_requested) + { + // Ctrl-C was hit previously? + } + else + { + // We are currently blocked on a child process. Upon return, transition_from_spawn_process() will be + // called and exit. + } + } + + private: + enum class CtrlCState + { + normal, + blocked_on_child, + exit_requested, + }; + + std::atomic m_state; + }; + + static CtrlCStateMachine g_ctrl_c_state; + } +#endif + + fs::path System::get_exe_path_of_current_process() { #if defined(_WIN32) wchar_t buf[_MAX_PATH]; @@ -51,7 +116,7 @@ namespace vcpkg::System #endif } - Optional to_cpu_architecture(const CStringView& arch) + Optional System::to_cpu_architecture(StringView arch) { if (Strings::case_insensitive_ascii_equals(arch, "x86")) return CPUArchitecture::X86; if (Strings::case_insensitive_ascii_equals(arch, "x64")) return CPUArchitecture::X64; @@ -61,7 +126,7 @@ namespace vcpkg::System return nullopt; } - CPUArchitecture get_host_processor() + CPUArchitecture System::get_host_processor() { #if defined(_WIN32) auto w6432 = get_environment_variable("PROCESSOR_ARCHITEW6432"); @@ -84,7 +149,7 @@ namespace vcpkg::System #endif } - std::vector get_supported_host_architectures() + std::vector System::get_supported_host_architectures() { std::vector supported_architectures; supported_architectures.push_back(get_host_processor()); @@ -98,20 +163,20 @@ namespace vcpkg::System return supported_architectures; } - CMakeVariable::CMakeVariable(const CStringView varname, const char* varvalue) + System::CMakeVariable::CMakeVariable(const StringView varname, const char* varvalue) : s(Strings::format(R"("-D%s=%s")", varname, varvalue)) { } - CMakeVariable::CMakeVariable(const CStringView varname, const std::string& varvalue) + System::CMakeVariable::CMakeVariable(const StringView varname, const std::string& varvalue) : CMakeVariable(varname, varvalue.c_str()) { } - CMakeVariable::CMakeVariable(const CStringView varname, const fs::path& path) + System::CMakeVariable::CMakeVariable(const StringView varname, const fs::path& path) : CMakeVariable(varname, path.generic_u8string()) { } - std::string make_cmake_cmd(const fs::path& cmake_exe, + std::string System::make_cmake_cmd(const fs::path& cmake_exe, const fs::path& cmake_script, const std::vector& pass_variables) { @@ -187,7 +252,7 @@ namespace vcpkg::System for (auto&& var : vars) { - env_wstrings.push_back(Strings::to_utf16(var.c_str())); + env_wstrings.push_back(Strings::to_utf16(var)); } } @@ -228,13 +293,11 @@ namespace vcpkg::System #if defined(_WIN32) /// If non-null, an environment block to use for the new process. If null, the new /// process will inherit the current environment. - static void windows_create_process(const CStringView cmd_line, - const wchar_t* maybe_environment, - DWORD dwCreationFlags, - PROCESS_INFORMATION* process_info) noexcept + static void windows_create_process(const StringView cmd_line, + const wchar_t* environment_block, + PROCESS_INFORMATION& process_info, + DWORD dwCreationFlags) noexcept { - Checks::check_exit(VCPKG_LINE_INFO, process_info != nullptr); - STARTUPINFOW startup_info; memset(&startup_info, 0, sizeof(STARTUPINFOW)); startup_info.cb = sizeof(STARTUPINFOW); @@ -244,41 +307,40 @@ namespace vcpkg::System // Wrapping the command in a single set of quotes causes cmd.exe to correctly execute const std::string actual_cmd_line = Strings::format(R"###(cmd.exe /c "%s")###", cmd_line); - Debug::println("CreateProcessW(%s)", actual_cmd_line); + Debug::print("CreateProcessW(", actual_cmd_line, ")\n"); bool succeeded = TRUE == CreateProcessW(nullptr, Strings::to_utf16(actual_cmd_line).data(), nullptr, nullptr, FALSE, IDLE_PRIORITY_CLASS | CREATE_UNICODE_ENVIRONMENT | dwCreationFlags, - (void*)maybe_environment, + (void*)environment_block, nullptr, &startup_info, - process_info); + &process_info); Checks::check_exit(VCPKG_LINE_INFO, succeeded, "Process creation failed with error code: %lu", GetLastError()); } #endif #if defined(_WIN32) - void cmd_execute_no_wait(const CStringView cmd_line) noexcept + void System::cmd_execute_no_wait(StringView cmd_line) { auto timer = Chrono::ElapsedTimer::create_started(); PROCESS_INFORMATION process_info; memset(&process_info, 0, sizeof(PROCESS_INFORMATION)); - windows_create_process(cmd_line, nullptr, DETACHED_PROCESS, &process_info); + windows_create_process(cmd_line, nullptr, process_info, DETACHED_PROCESS); CloseHandle(process_info.hThread); CloseHandle(process_info.hProcess); - Debug::println("CreateProcessW() took %d us", static_cast(timer.microseconds())); + Debug::print("CreateProcessW() took ", static_cast(timer.microseconds()), " us\n"); } #endif - int cmd_execute_clean(const CStringView cmd_line, - const std::unordered_map& extra_env) noexcept + int System::cmd_execute_clean(const ZStringView cmd_line, const std::unordered_map& extra_env) { auto timer = Chrono::ElapsedTimer::create_started(); #if defined(_WIN32) @@ -286,14 +348,14 @@ namespace vcpkg::System PROCESS_INFORMATION process_info; memset(&process_info, 0, sizeof(PROCESS_INFORMATION)); - GlobalState::g_ctrl_c_state.transition_to_spawn_process(); + g_ctrl_c_state.transition_to_spawn_process(); auto clean_env = compute_clean_environment(extra_env); - windows_create_process(cmd_line, clean_env.c_str(), NULL, &process_info); + windows_create_process(cmd_line, clean_env.data(), process_info, NULL); CloseHandle(process_info.hThread); const DWORD result = WaitForSingleObject(process_info.hProcess, INFINITE); - GlobalState::g_ctrl_c_state.transition_from_spawn_process(); + g_ctrl_c_state.transition_from_spawn_process(); Checks::check_exit(VCPKG_LINE_INFO, result != WAIT_FAILED, "WaitForSingleObject failed"); DWORD exit_code = 0; @@ -301,56 +363,56 @@ namespace vcpkg::System CloseHandle(process_info.hProcess); - Debug::println("CreateProcessW() returned %lu after %d us", exit_code, static_cast(timer.microseconds())); - + Debug::print( + "CreateProcessW() returned ", exit_code, " after ", static_cast(timer.microseconds()), " us\n"); return static_cast(exit_code); #else - Debug::println("system(%s)", cmd_line.c_str()); + Debug::print("system(", cmd_line, ")\n"); fflush(nullptr); int rc = system(cmd_line.c_str()); - Debug::println("system() returned %d after %d us", rc, static_cast(timer.microseconds())); + Debug::print("system() returned ", rc, " after ", static_cast(timer.microseconds()), " us\n"); return rc; #endif } - int cmd_execute(const CStringView cmd_line) noexcept + int System::cmd_execute(const ZStringView cmd_line) { // Flush stdout before launching external process fflush(nullptr); #if defined(_WIN32) // We are wrap the command line in quotes to cause cmd.exe to correctly process it - const std::string& actual_cmd_line = Strings::format(R"###("%s")###", cmd_line); - Debug::println("_wsystem(%s)", actual_cmd_line); - GlobalState::g_ctrl_c_state.transition_to_spawn_process(); + auto actual_cmd_line = Strings::concat('"', cmd_line, '"'); + Debug::print("_wsystem(", actual_cmd_line, ")\n"); + g_ctrl_c_state.transition_to_spawn_process(); const int exit_code = _wsystem(Strings::to_utf16(actual_cmd_line).c_str()); - GlobalState::g_ctrl_c_state.transition_from_spawn_process(); - Debug::println("_wsystem() returned %d", exit_code); + g_ctrl_c_state.transition_from_spawn_process(); + Debug::print("_wsystem() returned ", exit_code, '\n'); #else - Debug::println("_system(%s)", cmd_line); + Debug::print("_system(", cmd_line, ")\n"); const int exit_code = system(cmd_line.c_str()); - Debug::println("_system() returned %d", exit_code); + Debug::print("_system() returned ", exit_code, '\n'); #endif return exit_code; } - ExitCodeAndOutput cmd_execute_and_capture_output(const CStringView cmd_line) noexcept + ExitCodeAndOutput System::cmd_execute_and_capture_output(const ZStringView cmd_line) { auto timer = Chrono::ElapsedTimer::create_started(); #if defined(_WIN32) const auto actual_cmd_line = Strings::format(R"###("%s 2>&1")###", cmd_line); - Debug::println("_wpopen(%s)", actual_cmd_line); + Debug::print("_wpopen(", actual_cmd_line, ")\n"); std::wstring output; wchar_t buf[1024]; - GlobalState::g_ctrl_c_state.transition_to_spawn_process(); + g_ctrl_c_state.transition_to_spawn_process(); // Flush stdout before launching external process fflush(stdout); const auto pipe = _wpopen(Strings::to_utf16(actual_cmd_line).c_str(), L"r"); if (pipe == nullptr) { - GlobalState::g_ctrl_c_state.transition_from_spawn_process(); + g_ctrl_c_state.transition_from_spawn_process(); return {1, Strings::to_utf8(output.c_str())}; } while (fgetws(buf, 1024, pipe)) @@ -359,12 +421,12 @@ namespace vcpkg::System } if (!feof(pipe)) { - GlobalState::g_ctrl_c_state.transition_from_spawn_process(); + g_ctrl_c_state.transition_from_spawn_process(); return {1, Strings::to_utf8(output.c_str())}; } const auto ec = _pclose(pipe); - GlobalState::g_ctrl_c_state.transition_from_spawn_process(); + g_ctrl_c_state.transition_from_spawn_process(); // On Win7, output from powershell calls contain a utf-8 byte order mark in the utf-16 stream, so we strip it // out if it is present. 0xEF,0xBB,0xBF is the UTF-8 byte-order mark @@ -374,13 +436,16 @@ namespace vcpkg::System output.erase(0, 3); } - Debug::println("_pclose() returned %d after %8d us", ec, static_cast(timer.microseconds())); - + Debug::print("_pclose() returned ", + ec, + " after ", + Strings::format("%8d", static_cast(timer.microseconds())), + " us\n"); return {ec, Strings::to_utf8(output.c_str())}; #else const auto actual_cmd_line = Strings::format(R"###(%s 2>&1)###", cmd_line); - Debug::println("popen(%s)", actual_cmd_line); + Debug::print("popen(", actual_cmd_line, ")\n"); std::string output; char buf[1024]; // Flush stdout before launching external process @@ -401,46 +466,13 @@ namespace vcpkg::System const auto ec = pclose(pipe); - Debug::println("_pclose() returned %d after %8d us", ec, (int)timer.microseconds()); + Debug::print("_pclose() returned ", ec, " after ", Strings::format("%8d", (int)timer.microseconds()), " us\n"); return {ec, output}; #endif } - void println() { putchar('\n'); } - - void print(const CStringView message) { fputs(message.c_str(), stdout); } - - void println(const CStringView message) - { - print(message); - println(); - } - - void print(const Color c, const CStringView message) - { -#if defined(_WIN32) - const HANDLE console_handle = GetStdHandle(STD_OUTPUT_HANDLE); - - CONSOLE_SCREEN_BUFFER_INFO console_screen_buffer_info {}; - GetConsoleScreenBufferInfo(console_handle, &console_screen_buffer_info); - const auto original_color = console_screen_buffer_info.wAttributes; - - SetConsoleTextAttribute(console_handle, static_cast(c) | (original_color & 0xF0)); - print(message); - SetConsoleTextAttribute(console_handle, original_color); -#else - print(message); -#endif - } - - void println(const Color c, const CStringView message) - { - print(c, message); - println(); - } - - Optional get_environment_variable(const CStringView varname) noexcept + Optional System::get_environment_variable(ZStringView varname) noexcept { #if defined(_WIN32) const auto w_varname = Strings::to_utf16(varname); @@ -467,37 +499,34 @@ namespace vcpkg::System return hkey_type == REG_SZ || hkey_type == REG_MULTI_SZ || hkey_type == REG_EXPAND_SZ; } - Optional get_registry_string(void* base_hkey, const CStringView sub_key, const CStringView valuename) + Optional System::get_registry_string(void* base_hkey, StringView sub_key, StringView valuename) { HKEY k = nullptr; const LSTATUS ec = RegOpenKeyExW(reinterpret_cast(base_hkey), Strings::to_utf16(sub_key).c_str(), NULL, KEY_READ, &k); if (ec != ERROR_SUCCESS) return nullopt; + auto w_valuename = Strings::to_utf16(valuename); + DWORD dw_buffer_size = 0; DWORD dw_type = 0; - auto rc = - RegQueryValueExW(k, Strings::to_utf16(valuename).c_str(), nullptr, &dw_type, nullptr, &dw_buffer_size); + auto rc = RegQueryValueExW(k, w_valuename.c_str(), nullptr, &dw_type, nullptr, &dw_buffer_size); if (rc != ERROR_SUCCESS || !is_string_keytype(dw_type) || dw_buffer_size == 0 || dw_buffer_size % sizeof(wchar_t) != 0) return nullopt; std::wstring ret; ret.resize(dw_buffer_size / sizeof(wchar_t)); - rc = RegQueryValueExW(k, - Strings::to_utf16(valuename).c_str(), - nullptr, - &dw_type, - reinterpret_cast(ret.data()), - &dw_buffer_size); + rc = RegQueryValueExW( + k, w_valuename.c_str(), nullptr, &dw_type, reinterpret_cast(ret.data()), &dw_buffer_size); if (rc != ERROR_SUCCESS || !is_string_keytype(dw_type) || dw_buffer_size != sizeof(wchar_t) * ret.size()) return nullopt; ret.pop_back(); // remove extra trailing null byte - return Strings::to_utf8(ret.c_str()); + return Strings::to_utf8(ret); } #else - Optional get_registry_string(void* base_hkey, const CStringView sub_key, const CStringView valuename) + Optional System::get_registry_string(void* base_hkey, StringView sub_key, StringView valuename) { return nullopt; } @@ -518,7 +547,7 @@ namespace vcpkg::System return PATH; } - const Optional& get_program_files_32_bit() + const Optional& System::get_program_files_32_bit() { static const auto PATH = []() -> Optional { auto value = System::get_environment_variable("ProgramFiles(x86)"); @@ -531,7 +560,7 @@ namespace vcpkg::System return PATH; } - const Optional& get_program_files_platform_bitness() + const Optional& System::get_program_files_platform_bitness() { static const auto PATH = []() -> Optional { auto value = System::get_environment_variable("ProgramW6432"); @@ -543,23 +572,27 @@ namespace vcpkg::System }(); return PATH; } + +#if defined(_WIN32) + static BOOL ctrl_handler(DWORD fdw_ctrl_type) + { + switch (fdw_ctrl_type) + { + case CTRL_C_EVENT: g_ctrl_c_state.transition_handle_ctrl_c(); return TRUE; + default: return FALSE; + } + } + + void System::register_console_ctrl_handler() + { + SetConsoleCtrlHandler(reinterpret_cast(ctrl_handler), TRUE); + } +#else + void System::register_console_ctrl_handler() {} +#endif } namespace vcpkg::Debug { - void println(const CStringView message) - { - if (GlobalState::debugging) - { - System::println("[DEBUG] %s", message); - } - } - - void println(const System::Color c, const CStringView message) - { - if (GlobalState::debugging) - { - System::println(c, "[DEBUG] %s", message); - } - } + std::atomic g_debugging(false); } diff --git a/toolsrc/src/vcpkg/base/system.print.cpp b/toolsrc/src/vcpkg/base/system.print.cpp new file mode 100644 index 000000000..c7c9981a7 --- /dev/null +++ b/toolsrc/src/vcpkg/base/system.print.cpp @@ -0,0 +1,28 @@ +#include "pch.h" + +#include + +namespace vcpkg::System +{ + namespace details + { + void print(StringView message) { fwrite(message.data(), 1, message.size(), stdout); } + + void print(const Color c, StringView message) + { +#if defined(_WIN32) + const HANDLE console_handle = GetStdHandle(STD_OUTPUT_HANDLE); + + CONSOLE_SCREEN_BUFFER_INFO console_screen_buffer_info{}; + GetConsoleScreenBufferInfo(console_handle, &console_screen_buffer_info); + const auto original_color = console_screen_buffer_info.wAttributes; + + SetConsoleTextAttribute(console_handle, static_cast(c) | (original_color & 0xF0)); + System::print2(message); + SetConsoleTextAttribute(console_handle, original_color); +#else + System::print2(message); +#endif + } + } +} diff --git a/toolsrc/src/vcpkg/binaryparagraph.cpp b/toolsrc/src/vcpkg/binaryparagraph.cpp index 73ca23df1..4b80debab 100644 --- a/toolsrc/src/vcpkg/binaryparagraph.cpp +++ b/toolsrc/src/vcpkg/binaryparagraph.cpp @@ -1,6 +1,7 @@ #include "pch.h" #include +#include #include #include @@ -37,7 +38,7 @@ namespace vcpkg parser.required_field(Fields::PACKAGE, name); std::string architecture; parser.required_field(Fields::ARCHITECTURE, architecture); - this->spec = PackageSpec::from_name_and_triplet(name, Triplet::from_canonical_name(architecture)) + this->spec = PackageSpec::from_name_and_triplet(name, Triplet::from_canonical_name(std::move(architecture))) .value_or_exit(VCPKG_LINE_INFO); } @@ -61,8 +62,7 @@ namespace vcpkg if (const auto err = parser.error_info(this->spec.to_string())) { - System::println( - System::Color::error, "Error: while parsing the Binary Paragraph for %s", this->spec.to_string()); + System::print2(System::Color::error, "Error: while parsing the Binary Paragraph for ", this->spec, '\n'); print_error_message(err); Checks::exit_fail(VCPKG_LINE_INFO); } diff --git a/toolsrc/src/vcpkg/build.cpp b/toolsrc/src/vcpkg/build.cpp index f20367e00..43f1a6288 100644 --- a/toolsrc/src/vcpkg/build.cpp +++ b/toolsrc/src/vcpkg/build.cpp @@ -6,7 +6,8 @@ #include #include #include -#include +#include +#include #include #include @@ -81,19 +82,18 @@ namespace vcpkg::Build::Command const auto build_timer = Chrono::ElapsedTimer::create_started(); const auto result = Build::build_package(paths, build_config, status_db); - System::println("Elapsed time for package %s: %s", spec.to_string(), build_timer.to_string()); + System::print2("Elapsed time for package ", spec, ": ", build_timer, '\n'); if (result.code == BuildResult::CASCADED_DUE_TO_MISSING_DEPENDENCIES) { - System::println(System::Color::error, - "The build command requires all dependencies to be already installed."); - System::println("The following dependencies are missing:"); - System::println(); + System::print2(System::Color::error, + "The build command requires all dependencies to be already installed.\n"); + System::print2("The following dependencies are missing:\n\n"); for (const auto& p : result.unmet_dependencies) { - System::println(" %s", p); + System::print2(" ", p, '\n'); } - System::println(); + System::print2('\n'); Checks::exit_fail(VCPKG_LINE_INFO); } @@ -101,8 +101,8 @@ namespace vcpkg::Build::Command if (result.code != BuildResult::SUCCEEDED) { - System::println(System::Color::error, Build::create_error_message(result.code, spec)); - System::println(Build::create_user_troubleshooting_message(spec)); + System::print2(System::Color::error, Build::create_error_message(result.code, spec), '\n'); + System::print2(Build::create_user_troubleshooting_message(spec), '\n'); Checks::exit_fail(VCPKG_LINE_INFO); } @@ -125,9 +125,9 @@ namespace vcpkg::Build::Command { // Build only takes a single package and all dependencies must already be installed const ParsedArguments options = args.parse_arguments(COMMAND_STRUCTURE); - const std::string command_argument = args.command_arguments.at(0); - const FullPackageSpec spec = - Input::check_and_get_full_package_spec(command_argument, default_triplet, COMMAND_STRUCTURE.example_text); + std::string first_arg = args.command_arguments.at(0); + const FullPackageSpec spec = Input::check_and_get_full_package_spec( + std::move(first_arg), default_triplet, COMMAND_STRUCTURE.example_text); Input::check_triplet(spec.package_spec.triplet(), paths); if (!spec.features.empty() && !GlobalState::feature_packages) { @@ -506,7 +506,7 @@ namespace vcpkg::Build std::string key = Strings::format("file_%03d", counter++); if (GlobalState::debugging) { - System::println("[DEBUG] mapping %s from %s", key, port_file.string()); + System::print2("[DEBUG] mapping ", key, " from ", port_file.u8string(), "\n"); } abi_tag_entries.emplace_back(AbiEntry{ key, vcpkg::Hash::get_file_hash(fs, port_file, "SHA1") }); } @@ -531,12 +531,12 @@ namespace vcpkg::Build if (GlobalState::debugging) { - System::println("[DEBUG] "); + System::print2("[DEBUG] \n"); for (auto&& entry : abi_tag_entries) { - System::println("[DEBUG] %s|%s", entry.key, entry.value); + System::print2("[DEBUG] ", entry.key, "|", entry.value, "\n"); } - System::println("[DEBUG] "); + System::print2("[DEBUG] \n"); } auto abi_tag_entries_missing = abi_tag_entries; @@ -552,9 +552,10 @@ namespace vcpkg::Build return AbiTagAndFile{Hash::get_file_hash(fs, abi_file_path, "SHA1"), abi_file_path}; } - System::println( - "Warning: binary caching disabled because abi keys are missing values:\n%s", - Strings::join("", abi_tag_entries_missing, [](const AbiEntry& e) { return " " + e.key + "\n"; })); + System::print2( + "Warning: binary caching disabled because abi keys are missing values:\n", + Strings::join("", abi_tag_entries_missing, [](const AbiEntry& e) { return " " + e.key + "\n"; }), + "\n"); return nullopt; } @@ -594,10 +595,8 @@ namespace vcpkg::Build #if defined(_WIN32) auto&& seven_zip_exe = paths.get_tool_exe(Tools::SEVEN_ZIP); - System::cmd_execute_clean(Strings::format(R"("%s" a "%s" "%s\*" >nul)", - seven_zip_exe.u8string(), - destination.u8string(), - source.u8string())); + System::cmd_execute_clean(Strings::format( + R"("%s" a "%s" "%s\*" >nul)", seven_zip_exe.u8string(), destination.u8string(), source.u8string())); #else System::cmd_execute_clean(Strings::format( R"(cd '%s' && zip --quiet -r '%s' *)", source.u8string(), destination.u8string())); @@ -664,7 +663,7 @@ namespace vcpkg::Build if (fs.exists(archive_path)) { - System::println("Using cached binary package: %s", archive_path.u8string()); + System::print2("Using cached binary package: ", archive_path.u8string(), "\n"); decompress_archive(paths, spec, archive_path); @@ -678,17 +677,17 @@ namespace vcpkg::Build { if (config.build_package_options.fail_on_tombstone == FailOnTombstone::YES) { - System::println("Found failure tombstone: %s", archive_tombstone_path.u8string()); + System::print2("Found failure tombstone: ", archive_tombstone_path.u8string(), "\n"); return BuildResult::BUILD_FAILED; } else { - System::println( - System::Color::warning, "Found failure tombstone: %s", archive_tombstone_path.u8string()); + System::print2( + System::Color::warning, "Found failure tombstone: ", archive_tombstone_path.u8string(), "\n"); } } - System::println("Could not locate cached archive: %s", archive_path.u8string()); + System::print2("Could not locate cached archive: ", archive_path.u8string(), "\n"); ExtendedBuildResult result = do_build_package_and_clean_buildtrees( paths, pre_build_info, spec, maybe_abi_tag_and_file.value_or(AbiTagAndFile{}).tag, config); @@ -709,13 +708,13 @@ namespace vcpkg::Build fs.rename_or_copy(tmp_archive_path, archive_path, ".tmp", ec); if (ec) { - System::println(System::Color::warning, - "Failed to store binary cache %s: %s", - archive_path.u8string(), - ec.message()); + System::printf(System::Color::warning, + "Failed to store binary cache %s: %s\n", + archive_path.u8string(), + ec.message()); } else - System::println("Stored binary cache: %s", archive_path.u8string()); + System::printf("Stored binary cache: %s\n", archive_path.u8string()); } else if (result.code == BuildResult::BUILD_FAILED || result.code == BuildResult::POST_BUILD_CHECKS_FAILED) { @@ -731,7 +730,10 @@ namespace vcpkg::Build { if (log_file.path().extension() == ".log") { - fs.copy_file(log_file.path(), tmp_log_path_destination / log_file.path().filename(), fs::stdfs::copy_options::none, ec); + fs.copy_file(log_file.path(), + tmp_log_path_destination / log_file.path().filename(), + fs::stdfs::copy_options::none, + ec); } } diff --git a/toolsrc/src/vcpkg/commands.autocomplete.cpp b/toolsrc/src/vcpkg/commands.autocomplete.cpp index 3b353feec..afef518eb 100644 --- a/toolsrc/src/vcpkg/commands.autocomplete.cpp +++ b/toolsrc/src/vcpkg/commands.autocomplete.cpp @@ -1,6 +1,6 @@ #include "pch.h" -#include +#include #include #include #include @@ -14,7 +14,7 @@ namespace vcpkg::Commands::Autocomplete std::vector&& results) { const SortedVector sorted_results(results); - System::println(Strings::join("\n", sorted_results)); + System::print2(Strings::join("\n", sorted_results), '\n'); Checks::exit_success(line_info); } @@ -137,7 +137,7 @@ namespace vcpkg::Commands::Autocomplete if (is_option) { results = Util::fmap(command.structure.options.switches, - [](const CommandSwitch& s) -> std::string { return s.name; }); + [](const CommandSwitch& s) -> std::string { return s.name.to_string(); }); auto settings = Util::fmap(command.structure.options.settings, [](auto&& s) { return s.name; }); results.insert(results.end(), settings.begin(), settings.end()); diff --git a/toolsrc/src/vcpkg/commands.buildexternal.cpp b/toolsrc/src/vcpkg/commands.buildexternal.cpp index 82d03db48..19b89c2f5 100644 --- a/toolsrc/src/vcpkg/commands.buildexternal.cpp +++ b/toolsrc/src/vcpkg/commands.buildexternal.cpp @@ -20,7 +20,7 @@ namespace vcpkg::Commands::BuildExternal const ParsedArguments options = args.parse_arguments(COMMAND_STRUCTURE); const FullPackageSpec spec = Input::check_and_get_full_package_spec( - args.command_arguments.at(0), default_triplet, COMMAND_STRUCTURE.example_text); + std::string(args.command_arguments.at(0)), default_triplet, COMMAND_STRUCTURE.example_text); Input::check_triplet(spec.package_spec.triplet(), paths); const fs::path port_dir = args.command_arguments.at(1); diff --git a/toolsrc/src/vcpkg/commands.cache.cpp b/toolsrc/src/vcpkg/commands.cache.cpp index 464f4f9ee..c321de3b5 100644 --- a/toolsrc/src/vcpkg/commands.cache.cpp +++ b/toolsrc/src/vcpkg/commands.cache.cpp @@ -1,7 +1,7 @@ #include "pch.h" #include -#include +#include #include #include #include @@ -43,7 +43,7 @@ namespace vcpkg::Commands::Cache const std::vector binary_paragraphs = read_all_binary_paragraphs(paths); if (binary_paragraphs.empty()) { - System::println("No packages are cached."); + System::print2("No packages are cached.\n"); Checks::exit_success(VCPKG_LINE_INFO); } @@ -51,8 +51,7 @@ namespace vcpkg::Commands::Cache { for (const BinaryParagraph& binary_paragraph : binary_paragraphs) { - const std::string displayname = binary_paragraph.displayname(); - System::println(displayname); + System::print2(binary_paragraph.displayname(), '\n'); } } else @@ -66,7 +65,7 @@ namespace vcpkg::Commands::Cache continue; } - System::println(displayname); + System::print2(displayname, '\n'); } } diff --git a/toolsrc/src/vcpkg/commands.ci.cpp b/toolsrc/src/vcpkg/commands.ci.cpp index 4ff503e1c..10cb7d9fe 100644 --- a/toolsrc/src/vcpkg/commands.ci.cpp +++ b/toolsrc/src/vcpkg/commands.ci.cpp @@ -327,11 +327,11 @@ namespace vcpkg::Commands::CI b_will_build = true; } - System::println("%40s: %1s %8s: %s", p->spec, (b_will_build ? "*" : " "), state, abi); + System::printf("%40s: %1s %8s: %s\n", p->spec, (b_will_build ? "*" : " "), state, abi); } } - System::print("Time to determine pass/fail: %s\n", timer.elapsed().to_string()); + System::printf("Time to determine pass/fail: %s\n", timer.elapsed()); return ret; } @@ -340,7 +340,7 @@ namespace vcpkg::Commands::CI { if (!GlobalState::g_binary_caching) { - System::println(System::Color::warning, "Warning: Running ci without binary caching!"); + System::print2(System::Color::warning, "Warning: Running ci without binary caching!\n"); } const ParsedArguments options = args.parse_arguments(COMMAND_STRUCTURE); @@ -356,11 +356,8 @@ namespace vcpkg::Commands::CI const auto is_dry_run = Util::Sets::contains(options.switches, OPTION_DRY_RUN); const auto purge_tombstones = Util::Sets::contains(options.switches, OPTION_PURGE_TOMBSTONES); - std::vector triplets; - for (const std::string& triplet : args.command_arguments) - { - triplets.push_back(Triplet::from_canonical_name(triplet)); - } + std::vector triplets = Util::fmap( + args.command_arguments, [](std::string s) { return Triplet::from_canonical_name(std::move(s)); }); if (triplets.empty()) { @@ -491,8 +488,8 @@ namespace vcpkg::Commands::CI for (auto&& result : results) { - System::println("\nTriplet: %s", result.triplet); - System::println("Total elapsed time: %s", result.summary.total_elapsed_time); + System::print2("\nTriplet: ", result.triplet, "\n"); + System::print2("Total elapsed time: ", result.summary.total_elapsed_time, "\n"); result.summary.print(); } diff --git a/toolsrc/src/vcpkg/commands.contact.cpp b/toolsrc/src/vcpkg/commands.contact.cpp index 9f86a67dc..afbdc1fa7 100644 --- a/toolsrc/src/vcpkg/commands.contact.cpp +++ b/toolsrc/src/vcpkg/commands.contact.cpp @@ -1,7 +1,8 @@ #include "pch.h" #include -#include +#include +#include #include #include #include @@ -45,15 +46,15 @@ namespace vcpkg::Commands::Contact #if defined(_WIN32) System::cmd_execute("start https://aka.ms/NPS_vcpkg"); - System::println("Default browser launched to https://aka.ms/NPS_vcpkg; thank you for your feedback!"); + System::print2("Default browser launched to https://aka.ms/NPS_vcpkg; thank you for your feedback!\n"); #else - System::println( - "Please navigate to https://aka.ms/NPS_vcpkg in your preferred browser. Thank you for your feedback!"); + System::print2("Please navigate to https://aka.ms/NPS_vcpkg in your preferred browser. Thank you for your " + "feedback!\n"); #endif } else { - System::println("Send an email to %s with any feedback.", email()); + System::print2("Send an email to ", email(), " with any feedback.\n"); } Checks::exit_success(VCPKG_LINE_INFO); } diff --git a/toolsrc/src/vcpkg/commands.cpp b/toolsrc/src/vcpkg/commands.cpp index db265514f..54e9346ba 100644 --- a/toolsrc/src/vcpkg/commands.cpp +++ b/toolsrc/src/vcpkg/commands.cpp @@ -1,6 +1,7 @@ #include "pch.h" #include +#include #include #include @@ -77,7 +78,7 @@ namespace vcpkg::Commands::Fetch const std::string tool = args.command_arguments[0]; const fs::path tool_path = paths.get_tool_exe(tool); - System::println(tool_path.u8string()); + System::print2(tool_path.u8string(), '\n'); Checks::exit_success(VCPKG_LINE_INFO); } } @@ -100,7 +101,7 @@ namespace vcpkg::Commands::Hash const fs::path file_to_hash = args.command_arguments[0]; const std::string algorithm = args.command_arguments.size() == 2 ? args.command_arguments[1] : "SHA512"; const std::string hash = vcpkg::Hash::get_file_hash(paths.get_filesystem(), file_to_hash, algorithm); - System::println(hash); + System::print2(hash, '\n'); Checks::exit_success(VCPKG_LINE_INFO); } } diff --git a/toolsrc/src/vcpkg/commands.create.cpp b/toolsrc/src/vcpkg/commands.create.cpp index dfb3ab784..a6f2c8838 100644 --- a/toolsrc/src/vcpkg/commands.create.cpp +++ b/toolsrc/src/vcpkg/commands.create.cpp @@ -1,7 +1,8 @@ #include "pch.h" +#include #include -#include +#include #include #include diff --git a/toolsrc/src/vcpkg/commands.dependinfo.cpp b/toolsrc/src/vcpkg/commands.dependinfo.cpp index 455f3b7c5..c4441883c 100644 --- a/toolsrc/src/vcpkg/commands.dependinfo.cpp +++ b/toolsrc/src/vcpkg/commands.dependinfo.cpp @@ -1,7 +1,7 @@ #include "pch.h" #include -#include +#include #include #include #include @@ -142,7 +142,7 @@ namespace vcpkg::Commands::DependInfo } else { - System::println(System::Color::warning, "package '%s' does not exist", requested_package); + System::print2(System::Color::warning, "package '", requested_package, "' does not exist\n"); } } @@ -168,7 +168,7 @@ namespace vcpkg::Commands::DependInfo if (!options.switches.empty()) { const std::string graph_as_string = create_graph_as_string(options.switches, source_control_files); - System::println(graph_as_string); + System::print2(graph_as_string, '\n'); Checks::exit_success(VCPKG_LINE_INFO); } @@ -176,7 +176,7 @@ namespace vcpkg::Commands::DependInfo { const SourceParagraph& source_paragraph = *source_control_file->core_paragraph; const auto s = Strings::join(", ", source_paragraph.depends, [](const Dependency& d) { return d.name(); }); - System::println("%s: %s", source_paragraph.name, s); + System::print2(source_paragraph.name, ": ", s, "\n"); } Checks::exit_success(VCPKG_LINE_INFO); diff --git a/toolsrc/src/vcpkg/commands.edit.cpp b/toolsrc/src/vcpkg/commands.edit.cpp index 83ddea014..b2309aa41 100644 --- a/toolsrc/src/vcpkg/commands.edit.cpp +++ b/toolsrc/src/vcpkg/commands.edit.cpp @@ -1,7 +1,8 @@ #include "pch.h" #include -#include +#include +#include #include #include #include @@ -16,7 +17,7 @@ namespace vcpkg::Commands::Edit struct RegKey { HKEY root; - const char *subkey; + StringLiteral subkey; } REGKEYS[] = { { HKEY_LOCAL_MACHINE, @@ -46,7 +47,7 @@ namespace vcpkg::Commands::Edit System::get_registry_string(keypath.root, keypath.subkey, "InstallLocation"); if (const auto c = code_installpath.get()) { - const fs::path install_path = fs::path(*c); + const fs::path install_path = fs::u8path(*c); output.push_back(install_path / "Code - Insiders.exe"); output.push_back(install_path / "Code.exe"); } @@ -186,12 +187,12 @@ namespace vcpkg::Commands::Edit const auto it = Util::find_if(candidate_paths, [&](const fs::path& p) { return fs.exists(p); }); if (it == candidate_paths.cend()) { - System::println( + System::print2( System::Color::error, - "Error: Visual Studio Code was not found and the environment variable EDITOR is not set or invalid."); - System::println("The following paths were examined:"); + "Error: Visual Studio Code was not found and the environment variable EDITOR is not set or invalid.\n"); + System::print2("The following paths were examined:\n"); Files::print_paths(candidate_paths); - System::println("You can also set the environmental variable EDITOR to your editor of choice."); + System::print2("You can also set the environmental variable EDITOR to your editor of choice.\n"); Checks::exit_fail(VCPKG_LINE_INFO); } diff --git a/toolsrc/src/vcpkg/commands.env.cpp b/toolsrc/src/vcpkg/commands.env.cpp index ea00617d4..b81aeae55 100644 --- a/toolsrc/src/vcpkg/commands.env.cpp +++ b/toolsrc/src/vcpkg/commands.env.cpp @@ -1,7 +1,7 @@ #include "pch.h" #include -#include +#include #include #include #include diff --git a/toolsrc/src/vcpkg/commands.exportifw.cpp b/toolsrc/src/vcpkg/commands.exportifw.cpp index 62725a90a..ba9e28233 100644 --- a/toolsrc/src/vcpkg/commands.exportifw.cpp +++ b/toolsrc/src/vcpkg/commands.exportifw.cpp @@ -1,5 +1,7 @@ #include "pch.h" +#include +#include #include #include #include @@ -81,7 +83,7 @@ namespace vcpkg::Export::IFW Checks::check_exit(VCPKG_LINE_INFO, !ec, "Could not create directory for package file %s", - package_xml_file_path.generic_string()); + package_xml_file_path.generic_u8string()); auto deps = Strings::join( ",", binary_paragraph.depends, [](const std::string& dep) { return "packages." + dep + ":"; }); @@ -126,7 +128,7 @@ namespace vcpkg::Export::IFW Checks::check_exit(VCPKG_LINE_INFO, !ec, "Could not create directory for package file %s", - package_xml_file_path.generic_string()); + package_xml_file_path.generic_u8string()); fs.write_contents(package_xml_file_path, Strings::format( R"###( @@ -150,7 +152,7 @@ namespace vcpkg::Export::IFW Checks::check_exit(VCPKG_LINE_INFO, !ec, "Could not create directory for package file %s", - package_xml_file_path.generic_string()); + package_xml_file_path.generic_u8string()); fs.write_contents(package_xml_file_path, Strings::format( @@ -183,7 +185,7 @@ namespace vcpkg::Export::IFW Checks::check_exit(VCPKG_LINE_INFO, !ec, "Could not create directory for package file %s", - package_xml_file_path.generic_string()); + package_xml_file_path.generic_u8string()); fs.write_contents(package_xml_file_path, Strings::format( R"###( @@ -204,7 +206,7 @@ namespace vcpkg::Export::IFW Checks::check_exit(VCPKG_LINE_INFO, !ec, "Could not create directory for package file %s", - package_xml_file_path.generic_string()); + package_xml_file_path.generic_u8string()); fs.write_contents(package_xml_file_path, Strings::format( R"###( @@ -230,7 +232,7 @@ namespace vcpkg::Export::IFW Checks::check_exit(VCPKG_LINE_INFO, !ec, "Could not create directory for package file %s", - package_xml_file_path.generic_string()); + package_xml_file_path.generic_u8string()); fs.write_contents(package_xml_file_path, Strings::format( @@ -256,7 +258,7 @@ namespace vcpkg::Export::IFW Checks::check_exit(VCPKG_LINE_INFO, !ec, "Could not create directory for configuration file %s", - config_xml_file_path.generic_string()); + config_xml_file_path.generic_u8string()); std::string formatted_repo_url; std::string ifw_repo_url = ifw_options.maybe_repository_url.value_or(""); @@ -286,7 +288,7 @@ namespace vcpkg::Export::IFW void export_maintenance_tool(const fs::path& ifw_packages_dir_path, const VcpkgPaths& paths) { - System::println("Exporting maintenance tool... "); + System::print2("Exporting maintenance tool...\n"); std::error_code ec; Files::Filesystem& fs = paths.get_filesystem(); @@ -297,10 +299,10 @@ namespace vcpkg::Export::IFW Checks::check_exit(VCPKG_LINE_INFO, !ec, "Could not create directory for package file %s", - tempmaintenancetool.generic_string()); + tempmaintenancetool.generic_u8string()); fs.copy_file(installerbase_exe, tempmaintenancetool, fs::copy_options::overwrite_existing, ec); Checks::check_exit( - VCPKG_LINE_INFO, !ec, "Could not write package file %s", tempmaintenancetool.generic_string()); + VCPKG_LINE_INFO, !ec, "Could not write package file %s", tempmaintenancetool.generic_u8string()); fs::path package_xml_file_path = ifw_packages_dir_path / "maintenance" / "meta" / "package.xml"; fs::path package_xml_dir_path = package_xml_file_path.parent_path(); @@ -308,7 +310,7 @@ namespace vcpkg::Export::IFW Checks::check_exit(VCPKG_LINE_INFO, !ec, "Could not create directory for package file %s", - package_xml_file_path.generic_string()); + package_xml_file_path.generic_u8string()); fs.write_contents(package_xml_file_path, Strings::format( R"###( @@ -328,9 +330,9 @@ namespace vcpkg::Export::IFW const fs::path script_destination = ifw_packages_dir_path / "maintenance" / "meta" / "maintenance.qs"; fs.copy_file(script_source, script_destination, fs::copy_options::overwrite_existing, ec); Checks::check_exit( - VCPKG_LINE_INFO, !ec, "Could not write package file %s", script_destination.generic_string()); + VCPKG_LINE_INFO, !ec, "Could not write package file %s", script_destination.generic_u8string()); - System::println("Exporting maintenance tool... done"); + System::print2("Exporting maintenance tool... done\n"); } void do_repository(const std::string& export_id, const Options& ifw_options, const VcpkgPaths& paths) @@ -339,14 +341,16 @@ namespace vcpkg::Export::IFW const fs::path packages_dir = get_packages_dir_path(export_id, ifw_options, paths); const fs::path repository_dir = get_repository_dir_path(export_id, ifw_options, paths); - System::println("Generating repository %s...", repository_dir.generic_string()); + System::print2("Generating repository ", repository_dir.generic_u8string(), "...\n"); std::error_code ec; Files::Filesystem& fs = paths.get_filesystem(); fs.remove_all(repository_dir, ec); - Checks::check_exit( - VCPKG_LINE_INFO, !ec, "Could not remove outdated repository directory %s", repository_dir.generic_string()); + Checks::check_exit(VCPKG_LINE_INFO, + !ec, + "Could not remove outdated repository directory %s", + repository_dir.generic_u8string()); const auto cmd_line = Strings::format(R"("%s" --packages "%s" "%s" > nul)", repogen_exe.u8string(), @@ -356,7 +360,8 @@ namespace vcpkg::Export::IFW const int exit_code = System::cmd_execute_clean(cmd_line); Checks::check_exit(VCPKG_LINE_INFO, exit_code == 0, "Error: IFW repository generating failed"); - System::println(System::Color::success, "Generating repository %s... done.", repository_dir.generic_string()); + System::printf( + System::Color::success, "Generating repository %s... done.\n", repository_dir.generic_u8string()); } void do_installer(const std::string& export_id, const Options& ifw_options, const VcpkgPaths& paths) @@ -367,7 +372,7 @@ namespace vcpkg::Export::IFW const fs::path repository_dir = get_repository_dir_path(export_id, ifw_options, paths); const fs::path installer_file = get_installer_file_path(export_id, ifw_options, paths); - System::println("Generating installer %s...", installer_file.generic_string()); + System::printf("Generating installer %s...\n", installer_file.generic_u8string()); std::string cmd_line; @@ -392,7 +397,7 @@ namespace vcpkg::Export::IFW const int exit_code = System::cmd_execute_clean(cmd_line); Checks::check_exit(VCPKG_LINE_INFO, exit_code == 0, "Error: IFW installer generating failed"); - System::println(System::Color::success, "Generating installer %s... done.", installer_file.generic_string()); + System::printf(System::Color::success, "Generating installer %s... done.\n", installer_file.generic_u8string()); } void do_export(const std::vector& export_plan, @@ -410,16 +415,16 @@ namespace vcpkg::Export::IFW Checks::check_exit(VCPKG_LINE_INFO, !ec, "Could not remove outdated packages directory %s", - ifw_packages_dir_path.generic_string()); + ifw_packages_dir_path.generic_u8string()); fs.create_directory(ifw_packages_dir_path, ec); Checks::check_exit( - VCPKG_LINE_INFO, !ec, "Could not create packages directory %s", ifw_packages_dir_path.generic_string()); + VCPKG_LINE_INFO, !ec, "Could not create packages directory %s", ifw_packages_dir_path.generic_u8string()); // Export maintenance tool export_maintenance_tool(ifw_packages_dir_path, paths); - System::println("Exporting packages %s... ", ifw_packages_dir_path.generic_string()); + System::printf("Exporting packages %s...\n", ifw_packages_dir_path.generic_u8string()); // execute the plan std::map unique_packages; @@ -431,8 +436,7 @@ namespace vcpkg::Export::IFW Checks::unreachable(VCPKG_LINE_INFO); } - const std::string display_name = action.spec.to_string(); - System::println("Exporting package %s... ", display_name); + System::print2("Exporting package ", action.spec, "...\n"); const BinaryParagraph& binary_paragraph = action.core_paragraph().value_or_exit(VCPKG_LINE_INFO); @@ -449,14 +453,13 @@ namespace vcpkg::Export::IFW (binary_paragraph.fullstem() + ".list")); Install::install_files_and_write_listfile(paths.get_filesystem(), paths.package_dir(action.spec), dirs); - System::println("Exporting package %s... done", display_name); } - System::println("Exporting packages %s... done", ifw_packages_dir_path.generic_string()); + System::printf("Exporting packages %s... done\n", ifw_packages_dir_path.generic_u8string()); const fs::path config_file = get_config_file_path(export_id, ifw_options, paths); - System::println("Generating configuration %s...", config_file.generic_string()); + System::printf("Generating configuration %s...\n", config_file.generic_u8string()); // Unique packages export_unique_packages(ifw_packages_dir_path, unique_packages, fs); @@ -472,7 +475,7 @@ namespace vcpkg::Export::IFW // Configuration export_config(export_id, ifw_options, paths); - System::println("Generating configuration %s... done.", config_file.generic_string()); + System::printf("Generating configuration %s... done.\n", config_file.generic_u8string()); // Do repository (optional) std::string ifw_repo_url = ifw_options.maybe_repository_url.value_or(""); diff --git a/toolsrc/src/vcpkg/commands.import.cpp b/toolsrc/src/vcpkg/commands.import.cpp index 4b595697a..a2fd5d15d 100644 --- a/toolsrc/src/vcpkg/commands.import.cpp +++ b/toolsrc/src/vcpkg/commands.import.cpp @@ -114,7 +114,7 @@ namespace vcpkg::Commands::Import Checks::check_exit(VCPKG_LINE_INFO, pghs.get() != nullptr, "Invalid control file %s for package", - control_file_path.generic_string()); + control_file_path.generic_u8string()); StatusParagraph spgh; spgh.package = BinaryParagraph(*pghs.get()); diff --git a/toolsrc/src/vcpkg/commands.integrate.cpp b/toolsrc/src/vcpkg/commands.integrate.cpp index acac3293f..026ab3b77 100644 --- a/toolsrc/src/vcpkg/commands.integrate.cpp +++ b/toolsrc/src/vcpkg/commands.integrate.cpp @@ -3,7 +3,8 @@ #include #include #include -#include +#include +#include #include #include #include @@ -73,7 +74,7 @@ namespace vcpkg::Commands::Integrate #if defined(_WIN32) static std::string get_nuget_id(const fs::path& vcpkg_root_dir) { - std::string dir_id = vcpkg_root_dir.generic_string(); + std::string dir_id = vcpkg_root_dir.generic_u8string(); std::replace(dir_id.begin(), dir_id.end(), '/', '.'); dir_id.erase(1, 1); // Erasing the ":" @@ -185,7 +186,7 @@ namespace vcpkg::Commands::Integrate { case ElevationPromptChoice::YES: break; case ElevationPromptChoice::NO: - System::println(System::Color::warning, "Warning: Previous integration file was not removed"); + System::print2(System::Color::warning, "Warning: Previous integration file was not removed\n"); Checks::exit_fail(VCPKG_LINE_INFO); default: Checks::unreachable(VCPKG_LINE_INFO); } @@ -219,7 +220,7 @@ namespace vcpkg::Commands::Integrate { case ElevationPromptChoice::YES: break; case ElevationPromptChoice::NO: - System::println(System::Color::warning, "Warning: integration was not applied"); + System::print2(System::Color::warning, "Warning: integration was not applied\n"); Checks::exit_fail(VCPKG_LINE_INFO); default: Checks::unreachable(VCPKG_LINE_INFO); } @@ -247,17 +248,19 @@ namespace vcpkg::Commands::Integrate const fs::path appdata_src_path = tmp_dir / "vcpkg.user.targets"; fs.write_contents(appdata_src_path, - create_appdata_targets_shortcut(paths.buildsystems_msbuild_targets.string())); + create_appdata_targets_shortcut(paths.buildsystems_msbuild_targets.u8string())); auto appdata_dst_path = get_appdata_targets_path(); const auto rc = fs.copy_file(appdata_src_path, appdata_dst_path, fs::copy_options::overwrite_existing, ec); if (!rc || ec) { - System::println(System::Color::error, - "Error: Failed to copy file: %s -> %s", - appdata_src_path.string(), - appdata_dst_path.string()); + System::print2(System::Color::error, + "Error: Failed to copy file: ", + appdata_src_path.u8string(), + " -> ", + appdata_dst_path.u8string(), + "\n"); Checks::exit_fail(VCPKG_LINE_INFO); } } @@ -268,26 +271,28 @@ namespace vcpkg::Commands::Integrate fs.write_contents(pathtxt, paths.root.generic_u8string(), ec); if (ec) { - System::println(System::Color::error, "Error: Failed to write file: %s", pathtxt.string()); + System::print2(System::Color::error, "Error: Failed to write file: ", pathtxt.u8string(), "\n"); Checks::exit_fail(VCPKG_LINE_INFO); } - System::println(System::Color::success, "Applied user-wide integration for this vcpkg root."); + System::print2(System::Color::success, "Applied user-wide integration for this vcpkg root.\n"); const fs::path cmake_toolchain = paths.buildsystems / "vcpkg.cmake"; #if defined(_WIN32) - System::println( + System::printf( R"( All MSBuild C++ projects can now #include any installed libraries. Linking will be handled automatically. Installing new libraries will make them instantly available. -CMake projects should use: "-DCMAKE_TOOLCHAIN_FILE=%s")", - cmake_toolchain.generic_string()); +CMake projects should use: "-DCMAKE_TOOLCHAIN_FILE=%s" +)", + cmake_toolchain.generic_u8string()); #else - System::println( + System::printf( R"( -CMake projects should use: "-DCMAKE_TOOLCHAIN_FILE=%s")", - cmake_toolchain.generic_string()); +CMake projects should use: "-DCMAKE_TOOLCHAIN_FILE=%s" +)", + cmake_toolchain.generic_u8string()); #endif Checks::exit_success(VCPKG_LINE_INFO); @@ -310,11 +315,11 @@ CMake projects should use: "-DCMAKE_TOOLCHAIN_FILE=%s")", if (was_deleted) { - System::println(System::Color::success, "User-wide integration was removed"); + System::print2(System::Color::success, "User-wide integration was removed\n"); } else { - System::println(System::Color::success, "User-wide integration is not installed"); + System::print2(System::Color::success, "User-wide integration is not installed\n"); } Checks::exit_success(VCPKG_LINE_INFO); @@ -354,17 +359,18 @@ CMake projects should use: "-DCMAKE_TOOLCHAIN_FILE=%s")", const fs::path nuget_package = buildsystems_dir / Strings::format("%s.%s.nupkg", nuget_id, nupkg_version); Checks::check_exit( VCPKG_LINE_INFO, exit_code == 0 && fs.exists(nuget_package), "Error: NuGet package creation failed"); - System::println(System::Color::success, "Created nupkg: %s", nuget_package.string()); + System::print2(System::Color::success, "Created nupkg: ", nuget_package.u8string(), '\n'); auto source_path = buildsystems_dir.u8string(); source_path = Strings::replace_all(std::move(source_path), "`", "``"); - System::println(R"( + System::printf(R"( With a project open, go to Tools->NuGet Package Manager->Package Manager Console and paste: Install-Package %s -Source "%s" + )", - nuget_id, - source_path); + nuget_id, + source_path); Checks::exit_success(VCPKG_LINE_INFO); } @@ -389,12 +395,12 @@ With a project open, go to Tools->NuGet Package Manager->Package Manager Console if (rc) { - System::println(System::Color::error, - "%s\n" - "Could not run:\n" - " '%s'", - TITLE, - script_path.generic_string()); + System::printf(System::Color::error, + "%s\n" + "Could not run:\n" + " '%s'\n", + TITLE, + script_path.generic_u8string()); { auto locked_metrics = Metrics::g_metrics.lock(); @@ -432,7 +438,7 @@ With a project open, go to Tools->NuGet Package Manager->Package Manager Console if (!matches.empty()) { - System::print("vcpkg bash completion is already imported to your %s file.\n" + System::printf("vcpkg bash completion is already imported to your %s file.\n" "The following entries were found:\n" " %s\n" "Please make sure you have started a new bash shell for the changes to take effect.\n", @@ -441,7 +447,7 @@ With a project open, go to Tools->NuGet Package Manager->Package Manager Console Checks::exit_success(VCPKG_LINE_INFO); } - System::print("Adding vcpkg completion entry to %s\n", bashrc_path.u8string()); + System::printf("Adding vcpkg completion entry to %s\n", bashrc_path.u8string()); bashrc_content.push_back(Strings::format("source %s", completion_script_path.u8string())); fs.write_contents(bashrc_path, Strings::join("\n", bashrc_content) + '\n'); Checks::exit_success(VCPKG_LINE_INFO); diff --git a/toolsrc/src/vcpkg/commands.list.cpp b/toolsrc/src/vcpkg/commands.list.cpp index cadc06ad3..71738427c 100644 --- a/toolsrc/src/vcpkg/commands.list.cpp +++ b/toolsrc/src/vcpkg/commands.list.cpp @@ -1,6 +1,6 @@ #include "pch.h" -#include +#include #include #include #include @@ -14,14 +14,14 @@ namespace vcpkg::Commands::List { if (full_desc) { - System::println("%-50s %-16s %s", pgh.package.displayname(), pgh.package.version, pgh.package.description); + System::printf("%-50s %-16s %s\n", pgh.package.displayname(), pgh.package.version, pgh.package.description); } else { - System::println("%-50s %-16s %s", - vcpkg::shorten_text(pgh.package.displayname(), 50), - vcpkg::shorten_text(pgh.package.version, 16), - vcpkg::shorten_text(pgh.package.description, 51)); + System::printf("%-50s %-16s %s\n", + vcpkg::shorten_text(pgh.package.displayname(), 50), + vcpkg::shorten_text(pgh.package.version, 16), + vcpkg::shorten_text(pgh.package.description, 51)); } } @@ -48,7 +48,7 @@ namespace vcpkg::Commands::List if (installed_ipv.empty()) { - System::println("No packages are installed. Did you mean `search`?"); + System::print2("No packages are installed. Did you mean `search`?\n"); Checks::exit_success(VCPKG_LINE_INFO); } @@ -63,11 +63,13 @@ namespace vcpkg::Commands::List return lhs->package.displayname() < rhs->package.displayname(); }); + const auto enable_fulldesc = Util::Sets::contains(options.switches, OPTION_FULLDESC.to_string()); + if (args.command_arguments.empty()) { for (const StatusParagraph* status_paragraph : installed_packages) { - do_print(*status_paragraph, Util::Sets::contains(options.switches, OPTION_FULLDESC)); + do_print(*status_paragraph, enable_fulldesc); } } else @@ -81,7 +83,7 @@ namespace vcpkg::Commands::List continue; } - do_print(*status_paragraph, Util::Sets::contains(options.switches, OPTION_FULLDESC)); + do_print(*status_paragraph, enable_fulldesc); } } diff --git a/toolsrc/src/vcpkg/commands.owns.cpp b/toolsrc/src/vcpkg/commands.owns.cpp index ee9584651..58ed69e8b 100644 --- a/toolsrc/src/vcpkg/commands.owns.cpp +++ b/toolsrc/src/vcpkg/commands.owns.cpp @@ -1,6 +1,6 @@ #include "pch.h" -#include +#include #include #include #include @@ -18,7 +18,7 @@ namespace vcpkg::Commands::Owns { if (file.find(file_substr) != std::string::npos) { - System::println("%s: %s", pgh.package.displayname(), file); + System::print2(pgh.package.displayname(), ": ", file, '\n'); } } } diff --git a/toolsrc/src/vcpkg/commands.portsdiff.cpp b/toolsrc/src/vcpkg/commands.portsdiff.cpp index 2d2b4bd5f..b30c38f43 100644 --- a/toolsrc/src/vcpkg/commands.portsdiff.cpp +++ b/toolsrc/src/vcpkg/commands.portsdiff.cpp @@ -6,7 +6,8 @@ #include #include -#include +#include +#include #include namespace vcpkg::Commands::PortsDiff @@ -71,7 +72,7 @@ namespace vcpkg::Commands::PortsDiff for (const std::string& name : ports_to_print) { const VersionT& version = names_and_versions.at(name); - System::println(" - %-14s %-16s", name, version); + System::printf(" - %-14s %-16s\n", name, version); } } @@ -155,14 +156,14 @@ namespace vcpkg::Commands::PortsDiff const std::vector& added_ports = setp.only_left; if (!added_ports.empty()) { - System::println("\nThe following %zd ports were added:", added_ports.size()); + System::printf("\nThe following %zd ports were added:\n", added_ports.size()); do_print_name_and_version(added_ports, current_names_and_versions); } const std::vector& removed_ports = setp.only_right; if (!removed_ports.empty()) { - System::println("\nThe following %zd ports were removed:", removed_ports.size()); + System::printf("\nThe following %zd ports were removed:\n", removed_ports.size()); do_print_name_and_version(removed_ports, previous_names_and_versions); } @@ -172,16 +173,16 @@ namespace vcpkg::Commands::PortsDiff if (!updated_ports.empty()) { - System::println("\nThe following %zd ports were updated:", updated_ports.size()); + System::printf("\nThe following %zd ports were updated:\n", updated_ports.size()); for (const UpdatedPort& p : updated_ports) { - System::println(" - %-14s %-16s", p.port, p.version_diff.to_string()); + System::printf(" - %-14s %-16s\n", p.port, p.version_diff.to_string()); } } if (added_ports.empty() && removed_ports.empty() && updated_ports.empty()) { - System::println("There were no changes in the ports between the two commits."); + System::print2("There were no changes in the ports between the two commits.\n"); } Checks::exit_success(VCPKG_LINE_INFO); diff --git a/toolsrc/src/vcpkg/commands.search.cpp b/toolsrc/src/vcpkg/commands.search.cpp index 263c86698..a0afd69e1 100644 --- a/toolsrc/src/vcpkg/commands.search.cpp +++ b/toolsrc/src/vcpkg/commands.search.cpp @@ -1,6 +1,6 @@ #include "pch.h" -#include +#include #include #include #include @@ -12,34 +12,35 @@ namespace vcpkg::Commands::Search { static constexpr StringLiteral OPTION_FULLDESC = "--x-full-desc"; // TODO: This should find a better home, eventually - + static void do_print(const SourceParagraph& source_paragraph, bool full_desc) { if (full_desc) { - System::println( - "%-20s %-16s %s", source_paragraph.name, source_paragraph.version, source_paragraph.description); + System::printf( + "%-20s %-16s %s\n", source_paragraph.name, source_paragraph.version, source_paragraph.description); } else { - System::println("%-20s %-16s %s", - vcpkg::shorten_text(source_paragraph.name, 20), - vcpkg::shorten_text(source_paragraph.version, 16), - vcpkg::shorten_text(source_paragraph.description, 81)); + System::printf("%-20s %-16s %s\n", + vcpkg::shorten_text(source_paragraph.name, 20), + vcpkg::shorten_text(source_paragraph.version, 16), + vcpkg::shorten_text(source_paragraph.description, 81)); } } static void do_print(const std::string& name, const FeatureParagraph& feature_paragraph, bool full_desc) { + auto full_feature_name = Strings::concat(name, "[", feature_paragraph.name, "]"); if (full_desc) { - System::println("%-37s %s", name + "[" + feature_paragraph.name + "]", feature_paragraph.description); + System::printf("%-37s %s\n", full_feature_name, feature_paragraph.description); } else { - System::println("%-37s %s", - vcpkg::shorten_text(name + "[" + feature_paragraph.name + "]", 37), - vcpkg::shorten_text(feature_paragraph.description, 81)); + System::printf("%-37s %s\n", + vcpkg::shorten_text(full_feature_name, 37), + vcpkg::shorten_text(feature_paragraph.description, 81)); } } @@ -102,9 +103,9 @@ namespace vcpkg::Commands::Search } } - System::println( + System::print2( "\nIf your library is not listed, please open an issue at and/or consider making a pull request:\n" - " https://github.com/Microsoft/vcpkg/issues"); + " https://github.com/Microsoft/vcpkg/issues\n"); Checks::exit_success(VCPKG_LINE_INFO); } diff --git a/toolsrc/src/vcpkg/commands.upgrade.cpp b/toolsrc/src/vcpkg/commands.upgrade.cpp index 0e58b012d..29627db3d 100644 --- a/toolsrc/src/vcpkg/commands.upgrade.cpp +++ b/toolsrc/src/vcpkg/commands.upgrade.cpp @@ -10,6 +10,7 @@ #include #include +#include #include namespace vcpkg::Commands::Upgrade @@ -47,7 +48,7 @@ namespace vcpkg::Commands::Upgrade // input sanitization const std::vector specs = Util::fmap(args.command_arguments, [&](auto&& arg) { - return Input::check_and_get_package_spec(arg, default_triplet, COMMAND_STRUCTURE.example_text); + return Input::check_and_get_package_spec(std::string(arg), default_triplet, COMMAND_STRUCTURE.example_text); }); for (auto&& spec : specs) @@ -62,7 +63,7 @@ namespace vcpkg::Commands::Upgrade if (outdated_packages.empty()) { - System::println("All installed packages are up-to-date with the local portfiles."); + System::print2("All installed packages are up-to-date with the local portfiles.\n"); Checks::exit_success(VCPKG_LINE_INFO); } @@ -112,23 +113,29 @@ namespace vcpkg::Commands::Upgrade if (!up_to_date.empty()) { - System::println(System::Color::success, "The following packages are up-to-date:"); - System::println(Strings::join( - "", up_to_date, [](const PackageSpec& spec) { return " " + spec.to_string() + "\n"; })); + System::print2(System::Color::success, "The following packages are up-to-date:\n"); + System::print2(Strings::join("", + up_to_date, + [](const PackageSpec& spec) { return " " + spec.to_string() + "\n"; }), + '\n'); } if (!not_installed.empty()) { - System::println(System::Color::error, "The following packages are not installed:"); - System::println(Strings::join( - "", not_installed, [](const PackageSpec& spec) { return " " + spec.to_string() + "\n"; })); + System::print2(System::Color::error, "The following packages are not installed:\n"); + System::print2(Strings::join("", + not_installed, + [](const PackageSpec& spec) { return " " + spec.to_string() + "\n"; }), + '\n'); } if (!no_portfile.empty()) { - System::println(System::Color::error, "The following packages do not have a valid portfile:"); - System::println(Strings::join( - "", no_portfile, [](const PackageSpec& spec) { return " " + spec.to_string() + "\n"; })); + System::print2(System::Color::error, "The following packages do not have a valid portfile:\n"); + System::print2(Strings::join("", + no_portfile, + [](const PackageSpec& spec) { return " " + spec.to_string() + "\n"; }), + '\n'); } Checks::check_exit(VCPKG_LINE_INFO, not_installed.empty() && no_portfile.empty()); @@ -166,15 +173,15 @@ namespace vcpkg::Commands::Upgrade if (!no_dry_run) { - System::println(System::Color::warning, - "If you are sure you want to rebuild the above packages, run this command with the " - "--no-dry-run option."); + System::print2(System::Color::warning, + "If you are sure you want to rebuild the above packages, run this command with the " + "--no-dry-run option.\n"); Checks::exit_fail(VCPKG_LINE_INFO); } const Install::InstallSummary summary = Install::perform(plan, keep_going, paths, status_db); - System::println("\nTotal elapsed time: %s\n", summary.total_elapsed_time); + System::print2("\nTotal elapsed time: ", summary.total_elapsed_time, "\n\n"); if (keep_going == KeepGoing::YES) { diff --git a/toolsrc/src/vcpkg/commands.version.cpp b/toolsrc/src/vcpkg/commands.version.cpp index 2ad91b57d..7029c8bfd 100644 --- a/toolsrc/src/vcpkg/commands.version.cpp +++ b/toolsrc/src/vcpkg/commands.version.cpp @@ -1,6 +1,6 @@ #include "pch.h" -#include +#include #include #include #include @@ -60,15 +60,15 @@ namespace vcpkg::Commands::Version { if (maj1 != maj2 || min1 != min2 || rev1 != rev2) { - System::println(System::Color::warning, - "Warning: Different source is available for vcpkg (%d.%d.%d -> %d.%d.%d). Use " - ".\\bootstrap-vcpkg.bat to update.", - maj2, - min2, - rev2, - maj1, - min1, - rev1); + System::printf(System::Color::warning, + "Warning: Different source is available for vcpkg (%d.%d.%d -> %d.%d.%d). Use " + ".\\bootstrap-vcpkg.bat to update.\n", + maj2, + min2, + rev2, + maj1, + min1, + rev1); } } } @@ -85,10 +85,11 @@ namespace vcpkg::Commands::Version { Util::unused(args.parse_arguments(COMMAND_STRUCTURE)); - System::println("Vcpkg package management program version %s\n" - "\n" - "See LICENSE.txt for license information.", - version()); + System::print2("Vcpkg package management program version ", + version(), + "\n" + "\n" + "See LICENSE.txt for license information.\n"); Checks::exit_success(VCPKG_LINE_INFO); } } diff --git a/toolsrc/src/vcpkg/commands.xvsinstances.cpp b/toolsrc/src/vcpkg/commands.xvsinstances.cpp index d748b6b2f..542ebd56c 100644 --- a/toolsrc/src/vcpkg/commands.xvsinstances.cpp +++ b/toolsrc/src/vcpkg/commands.xvsinstances.cpp @@ -1,5 +1,6 @@ #include "pch.h" +#include #include #include #include @@ -22,7 +23,7 @@ namespace vcpkg::Commands::X_VSInstances const auto instances = vcpkg::VisualStudio::get_visual_studio_instances(paths); for (const std::string& instance : instances) { - System::println(instance); + System::print2(instance, '\n'); } Checks::exit_success(VCPKG_LINE_INFO); diff --git a/toolsrc/src/vcpkg/dependencies.cpp b/toolsrc/src/vcpkg/dependencies.cpp index 19d8e7ae8..8fde28929 100644 --- a/toolsrc/src/vcpkg/dependencies.cpp +++ b/toolsrc/src/vcpkg/dependencies.cpp @@ -580,9 +580,10 @@ namespace vcpkg::Dependencies auto res = follow_plus_dependencies(f, cluster, graph, graph_plan, prevent_default_features); if (res != MarkPlusResult::SUCCESS) { - System::println(System::Color::warning, - "Warning: could not reinstall feature %s", - FeatureSpec{cluster.spec, f}); + System::print2(System::Color::warning, + "Warning: could not reinstall feature ", + FeatureSpec{cluster.spec, f}, + "\n"); } } @@ -596,9 +597,10 @@ namespace vcpkg::Dependencies auto res = mark_plus(default_feature, cluster, graph, graph_plan, prevent_default_features); if (res != MarkPlusResult::SUCCESS) { - System::println(System::Color::warning, - "Warning: could not install new default feature %s", - FeatureSpec{cluster.spec, default_feature}); + System::print2(System::Color::warning, + "Warning: could not install new default feature ", + FeatureSpec{cluster.spec, default_feature}, + "\n"); } } } @@ -837,40 +839,42 @@ namespace vcpkg::Dependencies if (!excluded.empty()) { - System::println("The following packages are excluded:\n%s", actions_to_output_string(excluded)); + System::print2("The following packages are excluded:\n", actions_to_output_string(excluded), '\n'); } if (!already_installed_plans.empty()) { - System::println("The following packages are already installed:\n%s", - actions_to_output_string(already_installed_plans)); + System::print2("The following packages are already installed:\n", + actions_to_output_string(already_installed_plans), + '\n'); } if (!rebuilt_plans.empty()) { - System::println("The following packages will be rebuilt:\n%s", actions_to_output_string(rebuilt_plans)); + System::print2("The following packages will be rebuilt:\n", actions_to_output_string(rebuilt_plans), '\n'); } if (!new_plans.empty()) { - System::println("The following packages will be built and installed:\n%s", - actions_to_output_string(new_plans)); + System::print2( + "The following packages will be built and installed:\n", actions_to_output_string(new_plans), '\n'); } if (!only_install_plans.empty()) { - System::println("The following packages will be directly installed:\n%s", - actions_to_output_string(only_install_plans)); + System::print2("The following packages will be directly installed:\n", + actions_to_output_string(only_install_plans), + '\n'); } if (has_non_user_requested_packages) - System::println("Additional packages (*) will be modified to complete this operation."); + System::print2("Additional packages (*) will be modified to complete this operation.\n"); if (!remove_plans.empty() && !is_recursive) { - System::println(System::Color::warning, - "If you are sure you want to rebuild the above packages, run the command with the " - "--recurse option"); + System::print2(System::Color::warning, + "If you are sure you want to rebuild the above packages, run the command with the " + "--recurse option\n"); Checks::exit_fail(VCPKG_LINE_INFO); } } diff --git a/toolsrc/src/vcpkg/export.cpp b/toolsrc/src/vcpkg/export.cpp index eec9a39f2..870d2c49e 100644 --- a/toolsrc/src/vcpkg/export.cpp +++ b/toolsrc/src/vcpkg/export.cpp @@ -11,7 +11,8 @@ #include #include -#include +#include +#include #include namespace vcpkg::Export @@ -96,10 +97,10 @@ namespace vcpkg::Export switch (plan_type) { case ExportPlanType::ALREADY_BUILT: - System::println("The following packages are already built and will be exported:\n%s", as_string); + System::print2("The following packages are already built and will be exported:\n", as_string, '\n'); continue; case ExportPlanType::NOT_BUILT: - System::println("The following packages need to be built:\n%s", as_string); + System::print2("The following packages need to be built:\n", as_string, '\n'); continue; default: Checks::unreachable(VCPKG_LINE_INFO); } @@ -316,7 +317,7 @@ namespace vcpkg::Export // input sanitization ret.specs = Util::fmap(args.command_arguments, [&](auto&& arg) { - return Input::check_and_get_package_spec(arg, default_triplet, COMMAND_STRUCTURE.example_text); + return Input::check_and_get_package_spec(std::string(arg), default_triplet, COMMAND_STRUCTURE.example_text); }); ret.dry_run = options.switches.find(OPTION_DRY_RUN) != options.switches.cend(); ret.raw = options.switches.find(OPTION_RAW) != options.switches.cend(); @@ -329,9 +330,9 @@ namespace vcpkg::Export if (!ret.raw && !ret.nuget && !ret.ifw && !ret.zip && !ret.seven_zip && !ret.dry_run) { - System::println(System::Color::error, - "Must provide at least one export type: --raw --nuget --ifw --zip --7zip"); - System::print(COMMAND_STRUCTURE.example_text); + System::print2(System::Color::error, + "Must provide at least one export type: --raw --nuget --ifw --zip --7zip\n"); + System::print2(COMMAND_STRUCTURE.example_text); Checks::exit_fail(VCPKG_LINE_INFO); } @@ -382,12 +383,12 @@ namespace vcpkg::Export const fs::path cmake_toolchain = prefix / "scripts" / "buildsystems" / "vcpkg.cmake"; const System::CMakeVariable cmake_variable = System::CMakeVariable("CMAKE_TOOLCHAIN_FILE", cmake_toolchain.generic_string()); - System::println("\n" - "To use the exported libraries in CMake projects use:" - "\n" - " %s" - "\n", - cmake_variable.s); + System::print2("\n" + "To use the exported libraries in CMake projects use:" + "\n" + " ", + cmake_variable.s, + "\n\n"); } static void handle_raw_based_export(Span export_plan, @@ -411,7 +412,7 @@ namespace vcpkg::Export } const std::string display_name = action.spec.to_string(); - System::println("Exporting package %s... ", display_name); + System::print2("Exporting package ", display_name, "...\n"); const BinaryParagraph& binary_paragraph = action.core_paragraph().value_or_exit(VCPKG_LINE_INFO); @@ -421,7 +422,6 @@ namespace vcpkg::Export raw_exported_dir_path / "installed" / "vcpkg" / "info" / (binary_paragraph.fullstem() + ".list")); Install::install_files_and_write_listfile(paths.get_filesystem(), paths.package_dir(action.spec), dirs); - System::println(System::Color::success, "Exporting package %s... done", display_name); } // Copy files needed for integration @@ -429,48 +429,47 @@ namespace vcpkg::Export if (opts.raw) { - System::println( - System::Color::success, R"(Files exported at: "%s")", raw_exported_dir_path.generic_string()); + System::printf(System::Color::success, + R"(Files exported at: "%s")" + "\n", + raw_exported_dir_path.u8string()); print_next_step_info(raw_exported_dir_path); } if (opts.nuget) { - System::println("Creating nuget package... "); + System::print2("Packing nuget package...\n"); const std::string nuget_id = opts.maybe_nuget_id.value_or(raw_exported_dir_path.filename().string()); const std::string nuget_version = opts.maybe_nuget_version.value_or("1.0.0"); const fs::path output_path = do_nuget_export(paths, nuget_id, nuget_version, raw_exported_dir_path, export_to_path); - System::println(System::Color::success, "Creating nuget package... done"); - System::println(System::Color::success, "NuGet package exported at: %s", output_path.generic_string()); + System::print2(System::Color::success, "NuGet package exported at: ", output_path.u8string(), "\n"); - System::println(R"( + System::printf(R"( With a project open, go to Tools->NuGet Package Manager->Package Manager Console and paste: Install-Package %s -Source "%s" )" - "\n", - nuget_id, - output_path.parent_path().u8string()); + "\n\n", + nuget_id, + output_path.parent_path().u8string()); } if (opts.zip) { - System::println("Creating zip archive... "); + System::print2("Creating zip archive...\n"); const fs::path output_path = do_archive_export(paths, raw_exported_dir_path, export_to_path, ArchiveFormatC::ZIP); - System::println(System::Color::success, "Creating zip archive... done"); - System::println(System::Color::success, "Zip archive exported at: %s", output_path.generic_string()); + System::print2(System::Color::success, "Zip archive exported at: ", output_path.u8string(), "\n"); print_next_step_info("[...]"); } if (opts.seven_zip) { - System::println("Creating 7zip archive... "); + System::print2("Creating 7zip archive...\n"); const fs::path output_path = do_archive_export(paths, raw_exported_dir_path, export_to_path, ArchiveFormatC::SEVEN_ZIP); - System::println(System::Color::success, "Creating 7zip archive... done"); - System::println(System::Color::success, "7zip archive exported at: %s", output_path.generic_string()); + System::print2(System::Color::success, "7zip archive exported at: ", output_path.u8string(), "\n"); print_next_step_info("[...]"); } @@ -503,14 +502,14 @@ With a project open, go to Tools->NuGet Package Manager->Package Manager Console if (has_non_user_requested_packages) { - System::println(System::Color::warning, - "Additional packages (*) need to be exported to complete this operation."); + System::print2(System::Color::warning, + "Additional packages (*) need to be exported to complete this operation.\n"); } const auto it = group_by_plan_type.find(ExportPlanType::NOT_BUILT); if (it != group_by_plan_type.cend() && !it->second.empty()) { - System::println(System::Color::error, "There are packages that have not been built."); + System::print2(System::Color::error, "There are packages that have not been built.\n"); // No need to show all of them, just the user-requested ones. Dependency resolution will handle the rest. std::vector unbuilt = it->second; @@ -518,9 +517,10 @@ With a project open, go to Tools->NuGet Package Manager->Package Manager Console unbuilt, [](const ExportPlanAction* a) { return a->request_type != RequestType::USER_REQUESTED; }); const auto s = Strings::join(" ", unbuilt, [](const ExportPlanAction* a) { return a->spec.to_string(); }); - System::println("To build them, run:\n" - " vcpkg install %s", - s); + System::print2("To build them, run:\n" + " vcpkg install ", + s, + "\n"); Checks::exit_fail(VCPKG_LINE_INFO); } diff --git a/toolsrc/src/vcpkg/globalstate.cpp b/toolsrc/src/vcpkg/globalstate.cpp index a54c596fb..1a2c08474 100644 --- a/toolsrc/src/vcpkg/globalstate.cpp +++ b/toolsrc/src/vcpkg/globalstate.cpp @@ -14,47 +14,4 @@ namespace vcpkg std::atomic GlobalState::g_init_console_cp(0); std::atomic GlobalState::g_init_console_output_cp(0); std::atomic GlobalState::g_init_console_initialized(false); - - GlobalState::CtrlCStateMachine GlobalState::g_ctrl_c_state; - - GlobalState::CtrlCStateMachine::CtrlCStateMachine() : m_state(CtrlCState::normal) {} - - void GlobalState::CtrlCStateMachine::transition_to_spawn_process() noexcept - { - auto expected = CtrlCState::normal; - auto transitioned = m_state.compare_exchange_strong(expected, CtrlCState::blocked_on_child); - if (!transitioned) - { - // Ctrl-C was hit and is asynchronously executing on another thread - Checks::exit_fail(VCPKG_LINE_INFO); - } - } - void GlobalState::CtrlCStateMachine::transition_from_spawn_process() noexcept - { - auto expected = CtrlCState::blocked_on_child; - auto transitioned = m_state.compare_exchange_strong(expected, CtrlCState::normal); - if (!transitioned) - { - // Ctrl-C was hit while blocked on the child process - Checks::exit_fail(VCPKG_LINE_INFO); - } - } - void GlobalState::CtrlCStateMachine::transition_handle_ctrl_c() noexcept - { - auto prev_state = m_state.exchange(CtrlCState::exit_requested); - - if (prev_state == CtrlCState::normal) - { - // Not currently blocked on a child process and Ctrl-C has not been hit. - Checks::exit_fail(VCPKG_LINE_INFO); - } - else if (prev_state == CtrlCState::exit_requested) - { - // Ctrl-C was hit previously - } - else - { - // This is the case where we are currently blocked on a child process - } - } } diff --git a/toolsrc/src/vcpkg/help.cpp b/toolsrc/src/vcpkg/help.cpp index 5df878a91..bac44506d 100644 --- a/toolsrc/src/vcpkg/help.cpp +++ b/toolsrc/src/vcpkg/help.cpp @@ -1,6 +1,6 @@ #include "pch.h" -#include +#include #include #include #include @@ -34,9 +34,7 @@ namespace vcpkg::Help static void integrate_topic_fn(const VcpkgPaths&) { - System::print("Commands:\n" - "%s", - Commands::Integrate::INTEGRATE_COMMAND_HELPSTRING); + System::print2("Commands:\n", Commands::Integrate::INTEGRATE_COMMAND_HELPSTRING); } static void help_topics(const VcpkgPaths&); @@ -66,60 +64,65 @@ namespace vcpkg::Help static void help_topics(const VcpkgPaths&) { - System::println("Available help topics:\n" - " triplet\n" - " integrate" - "%s", - Strings::join("", topics, [](const Topic& topic) { return std::string("\n ") + topic.name; })); + System::print2("Available help topics:\n" + " triplet\n" + " integrate", + Strings::join("", topics, [](const Topic& topic) { return std::string("\n ") + topic.name; }), + "\n"); } void help_topic_valid_triplet(const VcpkgPaths& paths) { - System::println("Available architecture triplets:"); + System::print2("Available architecture triplets:\n"); for (auto&& triplet : paths.get_available_triplets()) { - System::println(" %s", triplet); + System::print2(" ", triplet, '\n'); } } void print_usage() { - System::println( - "Commands:\n" - " vcpkg search [pat] Search for packages available to be built\n" - " vcpkg install ... Install a package\n" - " vcpkg remove ... Uninstall a package\n" - " vcpkg remove --outdated Uninstall all out-of-date packages\n" - " vcpkg list List installed packages\n" - " vcpkg update Display list of packages for updating\n" - " vcpkg upgrade Rebuild all outdated packages\n" - " vcpkg hash [alg] Hash a file by specific algorithm, default SHA512\n" - " vcpkg help topics Display the list of help topics\n" - " vcpkg help Display help for a specific topic\n" - "\n" - "%s" // Integration help - "\n" - " vcpkg export ... [opt]... Exports a package\n" - " vcpkg edit Open up a port for editing (uses " ENVVAR(EDITOR) ", default 'code')\n" - " vcpkg import Import a pre-built library\n" - " vcpkg create \n" - " [archivename] Create a new package\n" - " vcpkg owns Search for files in installed packages\n" - " vcpkg env Creates a clean shell environment for development or compiling.\n" - " vcpkg version Display version information\n" - " vcpkg contact Display contact information to send feedback\n" - "\n" - "Options:\n" - " --triplet Specify the target architecture triplet.\n" - " (default: " ENVVAR(VCPKG_DEFAULT_TRIPLET) ", see 'vcpkg help triplet')\n" - "\n" - " --vcpkg-root Specify the vcpkg root directory\n" - " (default: " ENVVAR(VCPKG_ROOT) ")\n" - "\n" - " @response_file Specify a response file to provide additional parameters\n" - "\n" - "For more help (including examples) see the accompanying README.md.", - Commands::Integrate::INTEGRATE_COMMAND_HELPSTRING); + System::print2("Commands:\n" + " vcpkg search [pat] Search for packages available to be built\n" + " vcpkg install ... Install a package\n" + " vcpkg remove ... Uninstall a package\n" + " vcpkg remove --outdated Uninstall all out-of-date packages\n" + " vcpkg list List installed packages\n" + " vcpkg update Display list of packages for updating\n" + " vcpkg upgrade Rebuild all outdated packages\n" + " vcpkg hash [alg] Hash a file by specific algorithm, default SHA512\n" + " vcpkg help topics Display the list of help topics\n" + " vcpkg help Display help for a specific topic\n" + "\n", + Commands::Integrate::INTEGRATE_COMMAND_HELPSTRING, // Integration help + "\n" + " vcpkg export ... [opt]... Exports a package\n" + " vcpkg edit Open up a port for editing (uses " ENVVAR(EDITOR) // + ", default 'code')\n" + " vcpkg import Import a pre-built library\n" + " vcpkg create \n" + " [archivename] Create a new package\n" + " vcpkg owns Search for files in installed packages\n" + " vcpkg env Creates a clean shell environment for development or " + "compiling.\n" + " vcpkg version Display version information\n" + " vcpkg contact Display contact information to send feedback\n" + "\n" + "Options:\n" + " --triplet Specify the target architecture triplet.\n" + " (default: " ENVVAR(VCPKG_DEFAULT_TRIPLET) // + ", see 'vcpkg help triplet')\n" + "\n" + " --vcpkg-root Specify the vcpkg root " + "directory\n" + " (default: " ENVVAR(VCPKG_ROOT) // + ")\n" + "\n" + " @response_file Specify a " + "response file to provide additional parameters\n" + "\n" + "For more help (including examples) see the " + "accompanying README.md.\n"); } std::string create_example_string(const std::string& command_and_arguments) @@ -153,7 +156,7 @@ namespace vcpkg::Help Checks::exit_success(VCPKG_LINE_INFO); } - System::println(System::Color::error, "Error: unknown topic %s", topic); + System::print2(System::Color::error, "Error: unknown topic ", topic, '\n'); help_topics(paths); Checks::exit_fail(VCPKG_LINE_INFO); } diff --git a/toolsrc/src/vcpkg/input.cpp b/toolsrc/src/vcpkg/input.cpp index aee0fac7f..42f81cbb9 100644 --- a/toolsrc/src/vcpkg/input.cpp +++ b/toolsrc/src/vcpkg/input.cpp @@ -1,18 +1,19 @@ #include "pch.h" -#include +#include #include #include #include #include +#include -namespace vcpkg::Input +namespace vcpkg { - PackageSpec check_and_get_package_spec(const std::string& package_spec_as_string, - const Triplet& default_triplet, - CStringView example_text) + PackageSpec Input::check_and_get_package_spec(std::string&& spec_string, + const Triplet& default_triplet, + CStringView example_text) { - const std::string as_lowercase = Strings::ascii_to_lowercase(package_spec_as_string); + const std::string as_lowercase = Strings::ascii_to_lowercase(std::move(spec_string)); auto expected_spec = FullPackageSpec::from_string(as_lowercase, default_triplet); if (const auto spec = expected_spec.get()) { @@ -20,27 +21,27 @@ namespace vcpkg::Input } // Intentionally show the lowercased string - System::println(System::Color::error, "Error: %s: %s", vcpkg::to_string(expected_spec.error()), as_lowercase); - System::print(example_text); + System::print2(System::Color::error, "Error: ", expected_spec.error(), ": ", as_lowercase, '\n'); + System::print2(example_text); Checks::exit_fail(VCPKG_LINE_INFO); } - void check_triplet(const Triplet& t, const VcpkgPaths& paths) + void Input::check_triplet(const Triplet& t, const VcpkgPaths& paths) { if (!paths.is_valid_triplet(t)) { - System::println(System::Color::error, "Error: invalid triplet: %s", t); + System::print2(System::Color::error, "Error: invalid triplet: ", t, '\n'); Metrics::g_metrics.lock()->track_property("error", "invalid triplet: " + t.to_string()); Help::help_topic_valid_triplet(paths); Checks::exit_fail(VCPKG_LINE_INFO); } } - FullPackageSpec check_and_get_full_package_spec(const std::string& full_package_spec_as_string, - const Triplet& default_triplet, - CStringView example_text) + FullPackageSpec Input::check_and_get_full_package_spec(std::string&& full_package_spec_as_string, + const Triplet& default_triplet, + CStringView example_text) { - const std::string as_lowercase = Strings::ascii_to_lowercase(full_package_spec_as_string); + const std::string as_lowercase = Strings::ascii_to_lowercase(std::move(full_package_spec_as_string)); auto expected_spec = FullPackageSpec::from_string(as_lowercase, default_triplet); if (const auto spec = expected_spec.get()) { @@ -48,8 +49,8 @@ namespace vcpkg::Input } // Intentionally show the lowercased string - System::println(System::Color::error, "Error: %s: %s", vcpkg::to_string(expected_spec.error()), as_lowercase); - System::print(example_text); + System::print2(System::Color::error, "Error: ", expected_spec.error(), ": ", as_lowercase, '\n'); + System::print2(example_text); Checks::exit_fail(VCPKG_LINE_INFO); } } diff --git a/toolsrc/src/vcpkg/install.cpp b/toolsrc/src/vcpkg/install.cpp index 434876871..6d4eabc89 100644 --- a/toolsrc/src/vcpkg/install.cpp +++ b/toolsrc/src/vcpkg/install.cpp @@ -1,7 +1,7 @@ #include "pch.h" #include -#include +#include #include #include #include @@ -65,7 +65,7 @@ namespace vcpkg::Install const auto status = fs.symlink_status(file, ec); if (ec) { - System::println(System::Color::error, "failed: %s: %s", file.u8string(), ec.message()); + System::print2(System::Color::error, "failed: ", file.u8string(), ": ", ec.message(), "\n"); continue; } @@ -87,7 +87,7 @@ namespace vcpkg::Install fs.create_directory(target, ec); if (ec) { - System::println(System::Color::error, "failed: %s: %s", target.u8string(), ec.message()); + System::printf(System::Color::error, "failed: %s: %s\n", target.u8string(), ec.message()); } // Trailing backslash for directories @@ -98,15 +98,15 @@ namespace vcpkg::Install { if (fs.exists(target)) { - System::println(System::Color::warning, - "File %s was already present and will be overwritten", - target.u8string(), - ec.message()); + System::print2(System::Color::warning, + "File ", + target.u8string(), + " was already present and will be overwritten\n"); } fs.copy_file(file, target, fs::copy_options::overwrite_existing, ec); if (ec) { - System::println(System::Color::error, "failed: %s: %s", target.u8string(), ec.message()); + System::printf(System::Color::error, "failed: %s: %s\n", target.u8string(), ec.message()); } output.push_back(Strings::format(R"(%s/%s)", destination_subdirectory, suffix)); break; @@ -115,21 +115,21 @@ namespace vcpkg::Install { if (fs.exists(target)) { - System::println(System::Color::warning, - "File %s was already present and will be overwritten", - target.u8string(), - ec.message()); + System::print2(System::Color::warning, + "File ", + target.u8string(), + " was already present and will be overwritten\n"); } fs.copy_symlink(file, target, ec); if (ec) { - System::println(System::Color::error, "failed: %s: %s", target.u8string(), ec.message()); + System::printf(System::Color::error, "failed: %s: %s\n", target.u8string(), ec.message()); } output.push_back(Strings::format(R"(%s/%s)", destination_subdirectory, suffix)); break; } default: - System::println(System::Color::error, "failed: %s: cannot handle file type", file.u8string()); + System::printf(System::Color::error, "failed: %s: cannot handle file type\n", file.u8string()); break; } } @@ -209,13 +209,11 @@ namespace vcpkg::Install if (!intersection.empty()) { const fs::path triplet_install_path = paths.installed / triplet.canonical_name(); - System::println(System::Color::error, - "The following files are already installed in %s and are in conflict with %s", - triplet_install_path.generic_string(), - bcf.core_paragraph.spec); - System::print("\n "); - System::println(Strings::join("\n ", intersection)); - System::println(); + System::printf(System::Color::error, + "The following files are already installed in %s and are in conflict with %s\n", + triplet_install_path.generic_string(), + bcf.core_paragraph.spec); + System::print2("\n ", Strings::join("\n ", intersection), "\n\n"); return InstallResult::FILE_CONFLICTS; } @@ -278,20 +276,21 @@ namespace vcpkg::Install if (plan_type == InstallPlanType::ALREADY_INSTALLED) { if (use_head_version && is_user_requested) - System::println( - System::Color::warning, "Package %s is already installed -- not building from HEAD", display_name); + System::printf(System::Color::warning, + "Package %s is already installed -- not building from HEAD\n", + display_name); else - System::println(System::Color::success, "Package %s is already installed", display_name); + System::printf(System::Color::success, "Package %s is already installed\n", display_name); return BuildResult::SUCCEEDED; } auto aux_install = [&](const std::string& name, const BinaryControlFile& bcf) -> BuildResult { - System::println("Installing package %s... ", name); + System::printf("Installing package %s...\n", name); const auto install_result = install_package(paths, bcf, &status_db); switch (install_result) { case InstallResult::SUCCESS: - System::println(System::Color::success, "Installing package %s... done", name); + System::printf(System::Color::success, "Installing package %s... done\n", name); return BuildResult::SUCCEEDED; case InstallResult::FILE_CONFLICTS: return BuildResult::FILE_CONFLICTS; default: Checks::unreachable(VCPKG_LINE_INFO); @@ -301,9 +300,9 @@ namespace vcpkg::Install if (plan_type == InstallPlanType::BUILD_AND_INSTALL) { if (use_head_version) - System::println("Building package %s from HEAD... ", display_name_with_features); + System::printf("Building package %s from HEAD...\n", display_name_with_features); else - System::println("Building package %s... ", display_name_with_features); + System::printf("Building package %s...\n", display_name_with_features); auto result = [&]() -> Build::ExtendedBuildResult { const Build::BuildPackageConfig build_config{action.source_control_file.value_or_exit(VCPKG_LINE_INFO), @@ -316,11 +315,11 @@ namespace vcpkg::Install if (result.code != Build::BuildResult::SUCCEEDED) { - System::println(System::Color::error, Build::create_error_message(result.code, action.spec)); + System::print2(System::Color::error, Build::create_error_message(result.code, action.spec), "\n"); return result; } - System::println("Building package %s... done", display_name_with_features); + System::printf("Building package %s... done\n", display_name_with_features); auto bcf = std::make_unique( Paragraphs::try_load_cached_package(paths, action.spec).value_or_exit(VCPKG_LINE_INFO)); @@ -339,7 +338,7 @@ namespace vcpkg::Install if (plan_type == InstallPlanType::EXCLUDED) { - System::println(System::Color::warning, "Package %s is excluded", display_name); + System::printf(System::Color::warning, "Package %s is excluded\n", display_name); return BuildResult::EXCLUDED; } @@ -348,11 +347,11 @@ namespace vcpkg::Install void InstallSummary::print() const { - System::println("RESULTS"); + System::print2("RESULTS\n"); for (const SpecSummary& result : this->results) { - System::println(" %s: %s: %s", result.spec, Build::to_string(result.build_result.code), result.timing); + System::printf(" %s: %s: %s\n", result.spec, Build::to_string(result.build_result.code), result.timing); } std::map summary; @@ -366,10 +365,10 @@ namespace vcpkg::Install summary[r.build_result.code]++; } - System::println("\nSUMMARY"); + System::print2("\nSUMMARY\n"); for (const std::pair& entry : summary) { - System::println(" %s: %d", Build::to_string(entry.first), entry.second); + System::printf(" %s: %d\n", Build::to_string(entry.first), entry.second); } } @@ -391,7 +390,7 @@ namespace vcpkg::Install const PackageSpec& spec = action.spec(); const std::string display_name = spec.to_string(); - System::println("Starting package %zd/%zd: %s", counter, package_count, display_name); + System::printf("Starting package %zd/%zd: %s\n", counter, package_count, display_name); results.emplace_back(spec, &action); @@ -401,7 +400,7 @@ namespace vcpkg::Install if (result.code != BuildResult::SUCCEEDED && keep_going == KeepGoing::NO) { - System::println(Build::create_user_troubleshooting_message(install_action->spec)); + System::print2(Build::create_user_troubleshooting_message(install_action->spec), '\n'); Checks::exit_fail(VCPKG_LINE_INFO); } @@ -417,7 +416,7 @@ namespace vcpkg::Install } results.back().timing = build_timer.elapsed(); - System::println("Elapsed time for package %s: %s", display_name, results.back().timing.to_string()); + System::printf("Elapsed time for package %s: %s\n", display_name, results.back().timing); } return InstallSummary{std::move(results), timer.to_string()}; @@ -471,7 +470,7 @@ namespace vcpkg::Install auto maybe_contents = fs.read_contents(usage_file); if (auto p_contents = maybe_contents.get()) { - System::println(*p_contents); + System::print2(*p_contents, '\n'); } return; } @@ -525,15 +524,15 @@ namespace vcpkg::Install } else { - System::println("The package %s provides CMake targets:\n", bpgh.spec); + System::print2("The package ", bpgh.spec, " provides CMake targets:\n\n"); for (auto&& library_target_pair : library_targets) { auto config_it = config_files.find(library_target_pair.first); if (config_it != config_files.end()) - System::println(" find_package(%s CONFIG REQUIRED)", config_it->second); + System::printf(" find_package(%s CONFIG REQUIRED)\n", config_it->second); else - System::println(" find_package(%s CONFIG REQUIRED)", library_target_pair.first); + System::printf(" find_package(%s CONFIG REQUIRED)\n", library_target_pair.first); std::sort(library_target_pair.second.begin(), library_target_pair.second.end(), @@ -545,18 +544,18 @@ namespace vcpkg::Install if (library_target_pair.second.size() <= 4) { - System::println(" target_link_libraries(main PRIVATE %s)\n", - Strings::join(" ", library_target_pair.second)); + System::printf(" target_link_libraries(main PRIVATE %s)\n\n", + Strings::join(" ", library_target_pair.second)); } else { auto omitted = library_target_pair.second.size() - 4; library_target_pair.second.erase(library_target_pair.second.begin() + 4, library_target_pair.second.end()); - System::println(" # Note: %zd target(s) were omitted.\n" - " target_link_libraries(main PRIVATE %s)\n", - omitted, - Strings::join(" ", library_target_pair.second)); + System::printf(" # Note: %zd target(s) were omitted.\n" + " target_link_libraries(main PRIVATE %s)\n\n", + omitted, + Strings::join(" ", library_target_pair.second)); } } } @@ -574,7 +573,8 @@ namespace vcpkg::Install const ParsedArguments options = args.parse_arguments(COMMAND_STRUCTURE); const std::vector specs = Util::fmap(args.command_arguments, [&](auto&& arg) { - return Input::check_and_get_full_package_spec(arg, default_triplet, COMMAND_STRUCTURE.example_text); + return Input::check_and_get_full_package_spec( + std::string(arg), default_triplet, COMMAND_STRUCTURE.example_text); }); for (auto&& spec : specs) @@ -667,7 +667,7 @@ namespace vcpkg::Install const InstallSummary summary = perform(action_plan, keep_going, paths, status_db); - System::println("\nTotal elapsed time: %s\n", summary.total_elapsed_time); + System::print2("\nTotal elapsed time: ", summary.total_elapsed_time, "\n\n"); if (keep_going == KeepGoing::YES) { @@ -729,7 +729,8 @@ namespace vcpkg::Install case BuildResult::FILE_CONFLICTS: case BuildResult::BUILD_FAILED: result_string = "Fail"; - message_block = Strings::format("", to_string(code)); + message_block = + Strings::format("", to_string(code)); break; case BuildResult::EXCLUDED: case BuildResult::CASCADED_DUE_TO_MISSING_DEPENDENCIES: diff --git a/toolsrc/src/vcpkg/metrics.cpp b/toolsrc/src/vcpkg/metrics.cpp index c34f30974..5ca2b056a 100644 --- a/toolsrc/src/vcpkg/metrics.cpp +++ b/toolsrc/src/vcpkg/metrics.cpp @@ -7,7 +7,7 @@ #include #include #include -#include +#include #pragma comment(lib, "version") #pragma comment(lib, "winhttp") diff --git a/toolsrc/src/vcpkg/packagespec.cpp b/toolsrc/src/vcpkg/packagespec.cpp index 789aaca80..52edf4b6f 100644 --- a/toolsrc/src/vcpkg/packagespec.cpp +++ b/toolsrc/src/vcpkg/packagespec.cpp @@ -1,5 +1,6 @@ #include "pch.h" +#include #include #include #include @@ -16,8 +17,14 @@ namespace vcpkg std::string FeatureSpec::to_string() const { - if (feature().empty()) return spec().to_string(); - return Strings::format("%s[%s]:%s", name(), feature(), triplet()); + std::string ret; + this->to_string(ret); + return ret; + } + void FeatureSpec::to_string(std::string& out) const + { + if (feature().empty()) return spec().to_string(out); + Strings::append(out, name(), '[', feature(), "]:", triplet()); } std::vector FeatureSpec::from_strings_and_triplet(const std::vector& depends, @@ -71,7 +78,7 @@ namespace vcpkg if (auto p = res.get()) { FullPackageSpec fspec; - Triplet t = p->triplet.empty() ? default_triplet : Triplet::from_canonical_name(p->triplet); + Triplet t = p->triplet.empty() ? default_triplet : Triplet::from_canonical_name(std::move(p->triplet)); fspec.package_spec = PackageSpec::from_name_and_triplet(p->name, t).value_or_exit(VCPKG_LINE_INFO); fspec.features = std::move(p->features); return fspec; @@ -119,6 +126,7 @@ namespace vcpkg std::string PackageSpec::dir() const { return Strings::format("%s_%s", this->m_name, this->m_triplet); } std::string PackageSpec::to_string() const { return Strings::format("%s:%s", this->name(), this->triplet()); } + void PackageSpec::to_string(std::string& s) const { Strings::append(s, this->name(), ':', this->triplet()); } bool operator==(const PackageSpec& left, const PackageSpec& right) { diff --git a/toolsrc/src/vcpkg/packagespecparseresult.cpp b/toolsrc/src/vcpkg/packagespecparseresult.cpp index b12bd12d0..c5254f7be 100644 --- a/toolsrc/src/vcpkg/packagespecparseresult.cpp +++ b/toolsrc/src/vcpkg/packagespecparseresult.cpp @@ -18,4 +18,9 @@ namespace vcpkg default: Checks::unreachable(VCPKG_LINE_INFO); } } + + void to_string(std::string& out, PackageSpecParseResult p) + { + out.append(vcpkg::to_string(p).c_str()); + } } diff --git a/toolsrc/src/vcpkg/paragraphs.cpp b/toolsrc/src/vcpkg/paragraphs.cpp index 77c028937..45f939afd 100644 --- a/toolsrc/src/vcpkg/paragraphs.cpp +++ b/toolsrc/src/vcpkg/paragraphs.cpp @@ -1,6 +1,7 @@ #include "pch.h" #include +#include #include #include #include @@ -286,11 +287,11 @@ namespace vcpkg::Paragraphs { for (auto&& error : results.errors) { - System::println( - System::Color::warning, "Warning: an error occurred while parsing '%s'", error->name); + System::print2( + System::Color::warning, "Warning: an error occurred while parsing '", error->name, "'\n"); } - System::println(System::Color::warning, - "Use '--debug' to get more information about the parse failures.\n"); + System::print2(System::Color::warning, + "Use '--debug' to get more information about the parse failures.\n\n"); } } return std::move(results.paragraphs); diff --git a/toolsrc/src/vcpkg/postbuildlint.cpp b/toolsrc/src/vcpkg/postbuildlint.cpp index a62d4ece5..d6581c2b4 100644 --- a/toolsrc/src/vcpkg/postbuildlint.cpp +++ b/toolsrc/src/vcpkg/postbuildlint.cpp @@ -2,7 +2,8 @@ #include #include -#include +#include +#include #include #include #include @@ -88,9 +89,9 @@ namespace vcpkg::PostBuildLint const fs::path include_dir = package_dir / "include"; if (!fs.exists(include_dir) || fs.is_empty(include_dir)) { - System::println( - System::Color::warning, - "The folder /include is empty or not present. This indicates the library was not correctly installed."); + System::print2(System::Color::warning, + "The folder /include is empty or not present. This indicates the library was not correctly " + "installed.\n"); return LintStatus::ERROR_DETECTED; } @@ -109,10 +110,10 @@ namespace vcpkg::PostBuildLint if (!files_found.empty()) { - System::println(System::Color::warning, - "Include files should not be duplicated into the /debug/include directory. If this cannot " - "be disabled in the project cmake, use\n" - " file(REMOVE_RECURSE ${CURRENT_PACKAGES_DIR}/debug/include)"); + System::print2(System::Color::warning, + "Include files should not be duplicated into the /debug/include directory. If this cannot " + "be disabled in the project cmake, use\n" + " file(REMOVE_RECURSE ${CURRENT_PACKAGES_DIR}/debug/include)\n"); return LintStatus::ERROR_DETECTED; } @@ -125,9 +126,9 @@ namespace vcpkg::PostBuildLint if (fs.exists(debug_share)) { - System::println(System::Color::warning, - "/debug/share should not exist. Please reorganize any important files, then use\n" - " file(REMOVE_RECURSE ${CURRENT_PACKAGES_DIR}/debug/share)"); + System::print2(System::Color::warning, + "/debug/share should not exist. Please reorganize any important files, then use\n" + " file(REMOVE_RECURSE ${CURRENT_PACKAGES_DIR}/debug/share)\n"); return LintStatus::ERROR_DETECTED; } @@ -141,9 +142,9 @@ namespace vcpkg::PostBuildLint const fs::path lib_cmake = package_dir / "lib" / "cmake"; if (fs.exists(lib_cmake)) { - System::println( + System::printf( System::Color::warning, - "The /lib/cmake folder should be merged with /debug/lib/cmake and moved to /share/%s/cmake.", + "The /lib/cmake folder should be merged with /debug/lib/cmake and moved to /share/%s/cmake.\n", spec.name()); return LintStatus::ERROR_DETECTED; } @@ -175,9 +176,9 @@ namespace vcpkg::PostBuildLint if (!misplaced_cmake_files.empty()) { - System::println( + System::printf( System::Color::warning, - "The following cmake files were found outside /share/%s. Please place cmake files in /share/%s.", + "The following cmake files were found outside /share/%s. Please place cmake files in /share/%s.\n", spec.name(), spec.name()); Files::print_paths(misplaced_cmake_files); @@ -194,9 +195,9 @@ namespace vcpkg::PostBuildLint const fs::path lib_cmake_debug = package_dir / "debug" / "lib" / "cmake"; if (fs.exists(lib_cmake_debug)) { - System::println(System::Color::warning, - "The /debug/lib/cmake folder should be merged with /lib/cmake into /share/%s", - spec.name()); + System::printf(System::Color::warning, + "The /debug/lib/cmake folder should be merged with /lib/cmake into /share/%s\n", + spec.name()); return LintStatus::ERROR_DETECTED; } @@ -210,9 +211,9 @@ namespace vcpkg::PostBuildLint if (!dlls.empty()) { - System::println(System::Color::warning, - "\nThe following dlls were found in /lib or /debug/lib. Please move them to /bin or " - "/debug/bin, respectively."); + System::print2(System::Color::warning, + "\nThe following dlls were found in /lib or /debug/lib. Please move them to /bin or " + "/debug/bin, respectively.\n"); Files::print_paths(dlls); return LintStatus::ERROR_DETECTED; } @@ -251,18 +252,18 @@ namespace vcpkg::PostBuildLint } } - System::println(System::Color::warning, - "The software license must be available at ${CURRENT_PACKAGES_DIR}/share/%s/copyright", - spec.name()); + System::printf(System::Color::warning, + "The software license must be available at ${CURRENT_PACKAGES_DIR}/share/%s/copyright\n", + spec.name()); if (potential_copyright_files.size() == 1) // if there is only one candidate, provide the cmake lines needed to place it in the proper location { const fs::path found_file = potential_copyright_files[0]; const fs::path relative_path = found_file.string().erase( 0, current_buildtrees_dir.string().size() + 1); // The +1 is needed to remove the "/" - System::println( + System::printf( "\n file(COPY ${CURRENT_BUILDTREES_DIR}/%s DESTINATION ${CURRENT_PACKAGES_DIR}/share/%s)\n" - " file(RENAME ${CURRENT_PACKAGES_DIR}/share/%s/%s ${CURRENT_PACKAGES_DIR}/share/%s/copyright)", + " file(RENAME ${CURRENT_PACKAGES_DIR}/share/%s/%s ${CURRENT_PACKAGES_DIR}/share/%s/copyright)\n", relative_path.generic_string(), spec.name(), spec.name(), @@ -271,7 +272,7 @@ namespace vcpkg::PostBuildLint } else if (potential_copyright_files.size() > 1) { - System::println(System::Color::warning, "The following files are potential copyright files:"); + System::print2(System::Color::warning, "The following files are potential copyright files:\n"); Files::print_paths(potential_copyright_files); } return LintStatus::ERROR_DETECTED; @@ -284,9 +285,9 @@ namespace vcpkg::PostBuildLint if (!exes.empty()) { - System::println( + System::print2( System::Color::warning, - "The following EXEs were found in /bin or /debug/bin. EXEs are not valid distribution targets."); + "The following EXEs were found in /bin or /debug/bin. EXEs are not valid distribution targets.\n"); Files::print_paths(exes); return LintStatus::ERROR_DETECTED; } @@ -312,9 +313,9 @@ namespace vcpkg::PostBuildLint if (!dlls_with_no_exports.empty()) { - System::println(System::Color::warning, "The following DLLs have no exports:"); + System::print2(System::Color::warning, "The following DLLs have no exports:\n"); Files::print_paths(dlls_with_no_exports); - System::println(System::Color::warning, "DLLs without any exports are likely a bug in the build script."); + System::print2(System::Color::warning, "DLLs without any exports are likely a bug in the build script.\n"); return LintStatus::ERROR_DETECTED; } @@ -346,9 +347,9 @@ namespace vcpkg::PostBuildLint if (!dlls_with_improper_uwp_bit.empty()) { - System::println(System::Color::warning, "The following DLLs do not have the App Container bit set:"); + System::print2(System::Color::warning, "The following DLLs do not have the App Container bit set:\n"); Files::print_paths(dlls_with_improper_uwp_bit); - System::println(System::Color::warning, "This bit is required for Windows Store apps."); + System::print2(System::Color::warning, "This bit is required for Windows Store apps.\n"); return LintStatus::ERROR_DETECTED; } @@ -381,13 +382,17 @@ namespace vcpkg::PostBuildLint static void print_invalid_architecture_files(const std::string& expected_architecture, std::vector binaries_with_invalid_architecture) { - System::println(System::Color::warning, "The following files were built for an incorrect architecture:"); - System::println(); + System::print2(System::Color::warning, "The following files were built for an incorrect architecture:\n\n"); for (const FileAndArch& b : binaries_with_invalid_architecture) { - System::println(" %s", b.file.generic_string()); - System::println("Expected %s, but was: %s", expected_architecture, b.actual_arch); - System::println(); + System::print2(" ", + b.file.u8string(), + "\n" + "Expected ", + expected_architecture, + ", but was: ", + b.actual_arch, + "\n\n"); } } @@ -468,8 +473,8 @@ namespace vcpkg::PostBuildLint return LintStatus::SUCCESS; } - System::println(System::Color::warning, - "DLLs should not be present in a static build, but the following DLLs were found:"); + System::print2(System::Color::warning, + "DLLs should not be present in a static build, but the following DLLs were found:\n"); Files::print_paths(dlls); return LintStatus::ERROR_DETECTED; } @@ -484,26 +489,26 @@ namespace vcpkg::PostBuildLint return LintStatus::SUCCESS; } - System::println(System::Color::warning, - "Mismatching number of debug and release binaries. Found %zd for debug but %zd for release.", - debug_count, - release_count); - System::println("Debug binaries"); + System::printf(System::Color::warning, + "Mismatching number of debug and release binaries. Found %zd for debug but %zd for release.\n", + debug_count, + release_count); + System::print2("Debug binaries\n"); Files::print_paths(debug_binaries); - System::println("Release binaries"); + System::print2("Release binaries\n"); Files::print_paths(release_binaries); if (debug_count == 0) { - System::println(System::Color::warning, "Debug binaries were not found"); + System::print2(System::Color::warning, "Debug binaries were not found\n"); } if (release_count == 0) { - System::println(System::Color::warning, "Release binaries were not found"); + System::print2(System::Color::warning, "Release binaries were not found\n"); } - System::println(); + System::print2("\n"); return LintStatus::ERROR_DETECTED; } @@ -517,11 +522,11 @@ namespace vcpkg::PostBuildLint if (lib_count == 0 && dll_count != 0) { - System::println(System::Color::warning, "Import libs were not present in %s", lib_dir.u8string()); - System::println(System::Color::warning, - "If this is intended, add the following line in the portfile:\n" - " SET(%s enabled)", - to_cmake_variable(BuildPolicy::DLLS_WITHOUT_LIBS)); + System::print2(System::Color::warning, "Import libs were not present in ", lib_dir.u8string(), "\n"); + System::printf(System::Color::warning, + "If this is intended, add the following line in the portfile:\n" + " SET(%s enabled)\n", + to_cmake_variable(BuildPolicy::DLLS_WITHOUT_LIBS)); return LintStatus::ERROR_DETECTED; } @@ -541,19 +546,21 @@ namespace vcpkg::PostBuildLint if (fs.exists(bin)) { - System::println(System::Color::warning, - R"(There should be no bin\ directory in a static build, but %s is present.)", - bin.u8string()); + System::printf(System::Color::warning, + R"(There should be no bin\ directory in a static build, but %s is present.)" + "\n", + bin.u8string()); } if (fs.exists(debug_bin)) { - System::println(System::Color::warning, - R"(There should be no debug\bin\ directory in a static build, but %s is present.)", - debug_bin.u8string()); + System::printf(System::Color::warning, + R"(There should be no debug\bin\ directory in a static build, but %s is present.)" + "\n", + debug_bin.u8string()); } - System::println( + System::print2( System::Color::warning, R"(If the creation of bin\ and/or debug\bin\ cannot be disabled, use this in the portfile to remove them)" "\n" @@ -563,7 +570,7 @@ namespace vcpkg::PostBuildLint R"###( file(REMOVE_RECURSE ${CURRENT_PACKAGES_DIR}/bin ${CURRENT_PACKAGES_DIR}/debug/bin))###" "\n" R"###( endif())###" - "\n"); + "\n\n"); return LintStatus::ERROR_DETECTED; } @@ -578,10 +585,10 @@ namespace vcpkg::PostBuildLint if (!empty_directories.empty()) { - System::println(System::Color::warning, "There should be no empty directories in %s", dir.generic_string()); - System::println("The following empty directories were found: "); + System::print2(System::Color::warning, "There should be no empty directories in ", dir.u8string(), "\n"); + System::print2("The following empty directories were found:\n"); Files::print_paths(empty_directories); - System::println( + System::print2( System::Color::warning, "If a directory should be populated but is not, this might indicate an error in the portfile.\n" "If the directories are not needed and their creation cannot be disabled, use something like this in " @@ -589,6 +596,7 @@ namespace vcpkg::PostBuildLint "\n" R"###( file(REMOVE_RECURSE ${CURRENT_PACKAGES_DIR}/a/dir ${CURRENT_PACKAGES_DIR}/some/other/dir))###" "\n" + "\n" "\n"); return LintStatus::ERROR_DETECTED; } @@ -635,18 +643,17 @@ namespace vcpkg::PostBuildLint if (!libs_with_invalid_crt.empty()) { - System::println(System::Color::warning, - "Expected %s crt linkage, but the following libs had invalid crt linkage:", - expected_build_type.to_string()); - System::println(); + System::printf(System::Color::warning, + "Expected %s crt linkage, but the following libs had invalid crt linkage:\n\n", + expected_build_type.to_string()); for (const BuildTypeAndFile btf : libs_with_invalid_crt) { - System::println(" %s: %s", btf.file.generic_string(), btf.build_type.to_string()); + System::printf(" %s: %s\n", btf.file.generic_string(), btf.build_type.to_string()); } - System::println(); + System::print2("\n"); - System::println(System::Color::warning, - "To inspect the lib files, use:\n dumpbin.exe /directives mylibfile.lib"); + System::print2(System::Color::warning, + "To inspect the lib files, use:\n dumpbin.exe /directives mylibfile.lib\n"); return LintStatus::ERROR_DETECTED; } @@ -686,16 +693,15 @@ namespace vcpkg::PostBuildLint if (!dlls_with_outdated_crt.empty()) { - System::println(System::Color::warning, "Detected outdated dynamic CRT in the following files:"); - System::println(); + System::print2(System::Color::warning, "Detected outdated dynamic CRT in the following files:\n\n"); for (const OutdatedDynamicCrtAndFile btf : dlls_with_outdated_crt) { - System::println(" %s: %s", btf.file.generic_string(), btf.outdated_crt.name); + System::print2(" ", btf.file.u8string(), ": ", btf.outdated_crt.name, "\n"); } - System::println(); + System::print2("\n"); - System::println(System::Color::warning, - "To inspect the dll files, use:\n dumpbin.exe /dependents mydllfile.dll"); + System::print2(System::Color::warning, + "To inspect the dll files, use:\n dumpbin.exe /dependents mydllfile.dll\n"); return LintStatus::ERROR_DETECTED; } @@ -707,8 +713,8 @@ namespace vcpkg::PostBuildLint std::vector misplaced_files = fs.get_files_non_recursive(dir); Util::erase_remove_if(misplaced_files, [&fs](const fs::path& path) { const std::string filename = path.filename().generic_string(); - if (Strings::case_insensitive_ascii_equals(filename.c_str(), "CONTROL") || - Strings::case_insensitive_ascii_equals(filename.c_str(), "BUILD_INFO")) + if (Strings::case_insensitive_ascii_equals(filename, "CONTROL") || + Strings::case_insensitive_ascii_equals(filename, "BUILD_INFO")) { return true; } @@ -718,9 +724,9 @@ namespace vcpkg::PostBuildLint if (!misplaced_files.empty()) { - System::println(System::Color::warning, "The following files are placed in\n%s: ", dir.u8string()); + System::print2(System::Color::warning, "The following files are placed in\n", dir.u8string(), ":\n"); Files::print_paths(misplaced_files); - System::println(System::Color::warning, "Files cannot be present in those directories.\n"); + System::print2(System::Color::warning, "Files cannot be present in those directories.\n\n"); return LintStatus::ERROR_DETECTED; } @@ -853,19 +859,21 @@ namespace vcpkg::PostBuildLint const PreBuildInfo& pre_build_info, const BuildInfo& build_info) { - System::println("-- Performing post-build validation"); + System::print2("-- Performing post-build validation\n"); const size_t error_count = perform_all_checks_and_return_error_count(spec, paths, pre_build_info, build_info); if (error_count != 0) { const fs::path portfile = paths.ports / spec.name() / "portfile.cmake"; - System::println(System::Color::error, - "Found %u error(s). Please correct the portfile:\n %s", - error_count, - portfile.string()); + System::print2(System::Color::error, + "Found ", + error_count, + " error(s). Please correct the portfile:\n ", + portfile.u8string(), + "\n"); } - System::println("-- Performing post-build validation done"); + System::print2("-- Performing post-build validation done\n"); return error_count; } diff --git a/toolsrc/src/vcpkg/remove.cpp b/toolsrc/src/vcpkg/remove.cpp index 921a04c23..685cdfdc3 100644 --- a/toolsrc/src/vcpkg/remove.cpp +++ b/toolsrc/src/vcpkg/remove.cpp @@ -1,6 +1,6 @@ #include "pch.h" -#include +#include #include #include #include @@ -58,7 +58,8 @@ namespace vcpkg::Remove const auto status = fs.symlink_status(target, ec); if (ec) { - System::println(System::Color::error, "failed: status(%s): %s", target.u8string(), ec.message()); + System::print2( + System::Color::error, "failed: status(", target.u8string(), "): ", ec.message(), "\n"); continue; } @@ -76,22 +77,22 @@ namespace vcpkg::Remove fs.remove(target, ec); if (ec) { - System::println( - System::Color::error, "failed: remove(%s): %s", target.u8string(), ec.message()); + System::printf( + System::Color::error, "failed: remove(%s): %s\n", target.u8string(), ec.message()); } #else - System::println( - System::Color::error, "failed: remove(%s): %s", target.u8string(), ec.message()); + System::printf( + System::Color::error, "failed: remove(%s): %s\n", target.u8string(), ec.message()); #endif } } else if (!fs::stdfs::exists(status)) { - System::println(System::Color::warning, "Warning: %s: file not found", target.u8string()); + System::printf(System::Color::warning, "Warning: %s: file not found\n", target.u8string()); } else { - System::println(System::Color::warning, "Warning: %s: cannot handle file type", target.u8string()); + System::printf(System::Color::warning, "Warning: %s: cannot handle file type\n", target.u8string()); } } @@ -105,7 +106,7 @@ namespace vcpkg::Remove fs.remove(*b, ec); if (ec) { - System::println(System::Color::error, "failed: %s", ec.message()); + System::print2(System::Color::error, "failed: ", ec.message(), "\n"); } } } @@ -143,10 +144,10 @@ namespace vcpkg::Remove switch (plan_type) { case RemovePlanType::NOT_INSTALLED: - System::println("The following packages are not installed, so not removed:\n%s", as_string); + System::print2("The following packages are not installed, so not removed:\n", as_string, "\n"); continue; case RemovePlanType::REMOVE: - System::println("The following packages will be removed:\n%s", as_string); + System::print2("The following packages will be removed:\n", as_string, "\n"); continue; default: Checks::unreachable(VCPKG_LINE_INFO); } @@ -163,12 +164,12 @@ namespace vcpkg::Remove switch (action.plan_type) { case RemovePlanType::NOT_INSTALLED: - System::println(System::Color::success, "Package %s is not installed", display_name); + System::printf(System::Color::success, "Package %s is not installed\n", display_name); break; case RemovePlanType::REMOVE: - System::println("Removing package %s... ", display_name); + System::printf("Removing package %s...\n", display_name); remove_package(paths, action.spec, status_db); - System::println(System::Color::success, "Removing package %s... done", display_name); + System::printf(System::Color::success, "Removing package %s... done\n", display_name); break; case RemovePlanType::UNKNOWN: default: Checks::unreachable(VCPKG_LINE_INFO); @@ -176,11 +177,11 @@ namespace vcpkg::Remove if (purge == Purge::YES) { - System::println("Purging package %s... ", display_name); + System::printf("Purging package %s...\n", display_name); Files::Filesystem& fs = paths.get_filesystem(); std::error_code ec; fs.remove_all(paths.packages / action.spec.dir(), ec); - System::println(System::Color::success, "Purging package %s... done", display_name); + System::printf(System::Color::success, "Purging package %s... done\n", display_name); } } @@ -224,7 +225,7 @@ namespace vcpkg::Remove { if (args.command_arguments.size() != 0) { - System::println(System::Color::error, "Error: 'remove' accepts either libraries or '--outdated'"); + System::print2(System::Color::error, "Error: 'remove' accepts either libraries or '--outdated'\n"); Checks::exit_fail(VCPKG_LINE_INFO); } @@ -235,7 +236,7 @@ namespace vcpkg::Remove if (specs.empty()) { - System::println(System::Color::success, "There are no outdated packages."); + System::print2(System::Color::success, "There are no outdated packages.\n"); Checks::exit_success(VCPKG_LINE_INFO); } } @@ -243,11 +244,12 @@ namespace vcpkg::Remove { if (args.command_arguments.size() < 1) { - System::println(System::Color::error, "Error: 'remove' accepts either libraries or '--outdated'"); + System::print2(System::Color::error, "Error: 'remove' accepts either libraries or '--outdated'\n"); Checks::exit_fail(VCPKG_LINE_INFO); } specs = Util::fmap(args.command_arguments, [&](auto&& arg) { - return Input::check_and_get_package_spec(arg, default_triplet, COMMAND_STRUCTURE.example_text); + return Input::check_and_get_package_spec( + std::string(arg), default_triplet, COMMAND_STRUCTURE.example_text); }); for (auto&& spec : specs) @@ -258,8 +260,8 @@ namespace vcpkg::Remove const bool purge_was_passed = Util::Sets::contains(options.switches, OPTION_PURGE); if (purge_was_passed && no_purge_was_passed) { - System::println(System::Color::error, "Error: cannot specify both --no-purge and --purge."); - System::print(COMMAND_STRUCTURE.example_text); + System::print2(System::Color::error, "Error: cannot specify both --no-purge and --purge.\n"); + System::print2(COMMAND_STRUCTURE.example_text); Checks::exit_fail(VCPKG_LINE_INFO); } const Purge purge = to_purge(purge_was_passed || !no_purge_was_passed); @@ -280,13 +282,13 @@ namespace vcpkg::Remove if (has_non_user_requested_packages) { - System::println(System::Color::warning, - "Additional packages (*) need to be removed to complete this operation."); + System::print2(System::Color::warning, + "Additional packages (*) need to be removed to complete this operation.\n"); if (!is_recursive) { - System::println(System::Color::warning, - "If you are sure you want to remove them, run the command with the --recurse option"); + System::print2(System::Color::warning, + "If you are sure you want to remove them, run the command with the --recurse option\n"); Checks::exit_fail(VCPKG_LINE_INFO); } } diff --git a/toolsrc/src/vcpkg/sourceparagraph.cpp b/toolsrc/src/vcpkg/sourceparagraph.cpp index baa8b070b..b495c5f1d 100644 --- a/toolsrc/src/vcpkg/sourceparagraph.cpp +++ b/toolsrc/src/vcpkg/sourceparagraph.cpp @@ -6,7 +6,8 @@ #include #include -#include +#include +#include #include namespace vcpkg @@ -47,8 +48,12 @@ namespace vcpkg Checks::check_exit(VCPKG_LINE_INFO, error_info != nullptr); if (error_info->error) { - System::println( - System::Color::error, "Error: while loading %s: %s", error_info->name, error_info->error.message()); + System::print2(System::Color::error, + "Error: while loading ", + error_info->name, + ": ", + error_info->error.message(), + '\n'); } } @@ -57,31 +62,36 @@ namespace vcpkg { if (!error_info->extra_fields.empty()) { - System::println(System::Color::error, - "Error: There are invalid fields in the control file of %s", - error_info->name); - System::println("The following fields were not expected:\n\n %s\n", - Strings::join("\n ", error_info->extra_fields)); + System::print2(System::Color::error, + "Error: There are invalid fields in the control file of ", + error_info->name, + '\n'); + System::print2("The following fields were not expected:\n\n ", + Strings::join("\n ", error_info->extra_fields), + "\n\n"); have_remaining_fields = true; } } if (have_remaining_fields) { - System::println("This is the list of valid fields (case-sensitive): \n\n %s\n", - Strings::join("\n ", get_list_of_valid_fields())); - System::println("Different source may be available for vcpkg. Use .\\bootstrap-vcpkg.bat to update.\n"); + System::print2("This is the list of valid fields (case-sensitive): \n\n ", + Strings::join("\n ", get_list_of_valid_fields()), + "\n\n"); + System::print2("Different source may be available for vcpkg. Use .\\bootstrap-vcpkg.bat to update.\n\n"); } for (auto&& error_info : error_info_list) { if (!error_info->missing_fields.empty()) { - System::println(System::Color::error, - "Error: There are missing fields in the control file of %s", - error_info->name); - System::println("The following fields were missing:\n\n %s\n", - Strings::join("\n ", error_info->missing_fields)); + System::print2(System::Color::error, + "Error: There are missing fields in the control file of ", + error_info->name, + '\n'); + System::print2("The following fields were missing:\n\n ", + Strings::join("\n ", error_info->missing_fields), + "\n\n"); } } } diff --git a/toolsrc/src/vcpkg/tools.cpp b/toolsrc/src/vcpkg/tools.cpp index 99a2f4fb8..7232971c7 100644 --- a/toolsrc/src/vcpkg/tools.cpp +++ b/toolsrc/src/vcpkg/tools.cpp @@ -8,9 +8,10 @@ #include #include #include -#include #include -#include +#include +#include +#include #include namespace vcpkg @@ -87,15 +88,15 @@ namespace vcpkg } const std::string tool_data = - StringRange::find_exactly_one_enclosed(XML, match_tool_entry[0], "").to_string(); + StringView::find_exactly_one_enclosed(XML, match_tool_entry[0], "").to_string(); const std::string version_as_string = - StringRange::find_exactly_one_enclosed(tool_data, "", "").to_string(); + StringView::find_exactly_one_enclosed(tool_data, "", "").to_string(); const std::string exe_relative_path = - StringRange::find_exactly_one_enclosed(tool_data, "", "").to_string(); - const std::string url = StringRange::find_exactly_one_enclosed(tool_data, "", "").to_string(); + StringView::find_exactly_one_enclosed(tool_data, "", "").to_string(); + const std::string url = StringView::find_exactly_one_enclosed(tool_data, "", "").to_string(); const std::string sha512 = - StringRange::find_exactly_one_enclosed(tool_data, "", "").to_string(); - auto archive_name = StringRange::find_at_most_one_enclosed(tool_data, "", ""); + StringView::find_exactly_one_enclosed(tool_data, "", "").to_string(); + auto archive_name = StringView::find_at_most_one_enclosed(tool_data, "", ""); const Optional> version = parse_version_string(version_as_string); Checks::check_exit(VCPKG_LINE_INFO, @@ -172,16 +173,16 @@ namespace vcpkg tool_name, version_as_string, tool_name); - System::println("A suitable version of %s was not found (required v%s). Downloading portable %s v%s...", - tool_name, - version_as_string, - tool_name, - version_as_string); + System::printf("A suitable version of %s was not found (required v%s). Downloading portable %s v%s...\n", + tool_name, + version_as_string, + tool_name, + version_as_string); auto& fs = paths.get_filesystem(); if (!fs.exists(tool_data.download_path)) { - System::println("Downloading %s...", tool_name); - System::println(" %s -> %s", tool_data.url, tool_data.download_path.string()); + System::print2("Downloading ", tool_name, "...\n"); + System::print2(" ", tool_data.url, " -> ", tool_data.download_path.u8string(), "\n"); Downloads::download_file(fs, tool_data.url, tool_data.download_path, tool_data.sha512); } else @@ -191,7 +192,7 @@ namespace vcpkg if (tool_data.is_archive) { - System::println("Extracting %s...", tool_name); + System::print2("Extracting ", tool_name, "...\n"); Archives::extract_archive(paths, tool_data.download_path, tool_data.tool_dir_path); } else @@ -286,7 +287,7 @@ cmake version 3.10.2 CMake suite maintained and supported by Kitware (kitware.com/cmake). */ - return StringRange::find_exactly_one_enclosed(rc.output, "cmake version ", "\n").to_string(); + return StringView::find_exactly_one_enclosed(rc.output, "cmake version ", "\n").to_string(); } }; @@ -352,7 +353,7 @@ Type 'NuGet help ' for help on a specific command. [[[List of available commands follows]]] */ - return StringRange::find_exactly_one_enclosed(rc.output, "NuGet Version: ", "\n").to_string(); + return StringView::find_exactly_one_enclosed(rc.output, "NuGet Version: ", "\n").to_string(); } }; diff --git a/toolsrc/src/vcpkg/triplet.cpp b/toolsrc/src/vcpkg/triplet.cpp index c4ad3f690..1abfa0b39 100644 --- a/toolsrc/src/vcpkg/triplet.cpp +++ b/toolsrc/src/vcpkg/triplet.cpp @@ -43,9 +43,9 @@ namespace vcpkg bool operator!=(const Triplet& left, const Triplet& right) { return !(left == right); } - Triplet Triplet::from_canonical_name(const std::string& triplet_as_string) + Triplet Triplet::from_canonical_name(std::string&& triplet_as_string) { - std::string s(Strings::ascii_to_lowercase(triplet_as_string)); + std::string s(Strings::ascii_to_lowercase(std::move(triplet_as_string))); const auto p = g_triplet_instances.emplace(std::move(s)); return &*p.first; } @@ -53,5 +53,6 @@ namespace vcpkg const std::string& Triplet::canonical_name() const { return this->m_instance->value; } const std::string& Triplet::to_string() const { return this->canonical_name(); } + void Triplet::to_string(std::string& out) const { out.append(this->canonical_name()); } size_t Triplet::hash_code() const { return m_instance->hash; } } diff --git a/toolsrc/src/vcpkg/update.cpp b/toolsrc/src/vcpkg/update.cpp index 57259f952..344192d59 100644 --- a/toolsrc/src/vcpkg/update.cpp +++ b/toolsrc/src/vcpkg/update.cpp @@ -1,6 +1,6 @@ #include "pch.h" -#include +#include #include #include #include @@ -53,7 +53,7 @@ namespace vcpkg::Update void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths) { args.parse_arguments(COMMAND_STRUCTURE); - System::println("Using local portfile versions. To update the local portfiles, use `git pull`."); + System::print2("Using local portfile versions. To update the local portfiles, use `git pull`.\n"); const StatusParagraphs status_db = database_load_check(paths); @@ -64,21 +64,22 @@ namespace vcpkg::Update if (outdated_packages.empty()) { - System::println("No packages need updating."); + System::print2("No packages need updating.\n"); } else { - System::println("The following packages differ from their port versions:"); + System::print2("The following packages differ from their port versions:\n"); for (auto&& package : outdated_packages) { - System::println(" %-32s %s", package.spec, package.version_diff.to_string()); + System::printf(" %-32s %s\n", package.spec, package.version_diff.to_string()); } - System::println("\n" - "To update these packages and all dependencies, run\n" - " .\\vcpkg upgrade\n" - "\n" - "To only remove outdated packages, run\n" - " .\\vcpkg remove --outdated\n"); + System::print2("\n" + "To update these packages and all dependencies, run\n" + " .\\vcpkg upgrade\n" + "\n" + "To only remove outdated packages, run\n" + " .\\vcpkg remove --outdated\n" + "\n"); } Checks::exit_success(VCPKG_LINE_INFO); diff --git a/toolsrc/src/vcpkg/vcpkgcmdarguments.cpp b/toolsrc/src/vcpkg/vcpkgcmdarguments.cpp index 5b3cf9ef1..8565c28f9 100644 --- a/toolsrc/src/vcpkg/vcpkgcmdarguments.cpp +++ b/toolsrc/src/vcpkg/vcpkgcmdarguments.cpp @@ -1,6 +1,6 @@ #include "pch.h" -#include +#include #include #include #include @@ -16,7 +16,7 @@ namespace vcpkg { if (arg_begin == arg_end) { - System::println(System::Color::error, "Error: expected value after %s", option_name); + System::print2(System::Color::error, "Error: expected value after ", option_name, '\n'); Metrics::g_metrics.lock()->track_property("error", "error option name"); Help::print_usage(); Checks::exit_fail(VCPKG_LINE_INFO); @@ -24,7 +24,7 @@ namespace vcpkg if (option_field != nullptr) { - System::println(System::Color::error, "Error: %s specified multiple times", option_name); + System::print2(System::Color::error, "Error: ", option_name, " specified multiple times\n"); Metrics::g_metrics.lock()->track_property("error", "error option specified multiple times"); Help::print_usage(); Checks::exit_fail(VCPKG_LINE_INFO); @@ -37,7 +37,7 @@ namespace vcpkg { if (option_field && option_field != new_setting) { - System::println(System::Color::error, "Error: conflicting values specified for --%s", option_name); + System::print2(System::Color::error, "Error: conflicting values specified for --", option_name, '\n'); Metrics::g_metrics.lock()->track_property("error", "error conflicting switches"); Help::print_usage(); Checks::exit_fail(VCPKG_LINE_INFO); @@ -65,7 +65,7 @@ namespace vcpkg auto lines = fs.read_lines(fs::u8path(arg)); if (!lines.has_value()) { - System::println(System::Color::error, "Error: Could not open response file %s", arg); + System::print2(System::Color::error, "Error: Could not open response file ", arg, '\n'); Checks::exit_fail(VCPKG_LINE_INFO); } std::copy(lines.get()->begin(), lines.get()->end(), std::back_inserter(v)); @@ -199,11 +199,11 @@ namespace vcpkg { if (actual_arg_count != command_structure.minimum_arity) { - System::println(System::Color::error, - "Error: '%s' requires %u arguments, but %u were provided.", - this->command, - command_structure.minimum_arity, - actual_arg_count); + System::printf(System::Color::error, + "Error: '%s' requires %u arguments, but %u were provided.\n", + this->command, + command_structure.minimum_arity, + actual_arg_count); failed = true; } } @@ -211,20 +211,20 @@ namespace vcpkg { if (actual_arg_count < command_structure.minimum_arity) { - System::println(System::Color::error, - "Error: '%s' requires at least %u arguments, but %u were provided", - this->command, - command_structure.minimum_arity, - actual_arg_count); + System::printf(System::Color::error, + "Error: '%s' requires at least %u arguments, but %u were provided\n", + this->command, + command_structure.minimum_arity, + actual_arg_count); failed = true; } if (actual_arg_count > command_structure.maximum_arity) { - System::println(System::Color::error, - "Error: '%s' requires at most %u arguments, but %u were provided", - this->command, - command_structure.maximum_arity, - actual_arg_count); + System::printf(System::Color::error, + "Error: '%s' requires at most %u arguments, but %u were provided\n", + this->command, + command_structure.maximum_arity, + actual_arg_count); failed = true; } } @@ -238,8 +238,8 @@ namespace vcpkg if (it->second.has_value()) { // Having a string value indicates it was passed like '--a=xyz' - System::println( - System::Color::error, "Error: The option '%s' does not accept an argument.", option.name); + System::printf( + System::Color::error, "Error: The option '%s' does not accept an argument.\n", option.name); failed = true; } else @@ -258,8 +258,8 @@ namespace vcpkg if (!it->second.has_value()) { // Not having a string value indicates it was passed like '--a' - System::println( - System::Color::error, "Error: The option '%s' must be passed an argument.", option.name); + System::printf( + System::Color::error, "Error: The option '%s' must be passed an argument.\n", option.name); failed = true; } else @@ -272,12 +272,12 @@ namespace vcpkg if (!options_copy.empty()) { - System::println(System::Color::error, "Unknown option(s) for command '%s':", this->command); + System::printf(System::Color::error, "Unknown option(s) for command '%s':\n", this->command); for (auto&& option : options_copy) { - System::println(" %s", option.first); + System::print2(" ", option.first, "\n"); } - System::println(); + System::print2("\n"); failed = true; } @@ -294,21 +294,21 @@ namespace vcpkg { if (!command_structure.example_text.empty()) { - System::println("%s", command_structure.example_text); + System::print2(command_structure.example_text, "\n"); } - System::println("Options:"); + System::print2("Options:\n"); for (auto&& option : command_structure.options.switches) { - System::println(" %-40s %s", option.name, option.short_help_text); + System::printf(" %-40s %s\n", option.name, option.short_help_text); } for (auto&& option : command_structure.options.settings) { - System::println(" %-40s %s", (option.name + "=..."), option.short_help_text); + System::printf(" %-40s %s\n", (option.name + "=..."), option.short_help_text); } - System::println(" %-40s %s", "--triplet ", "Set the default triplet for unqualified packages"); - System::println(" %-40s %s", - "--vcpkg-root ", - "Specify the vcpkg directory to use instead of current directory or tool directory"); + System::printf(" %-40s %s\n", "--triplet ", "Set the default triplet for unqualified packages"); + System::printf(" %-40s %s\n", + "--vcpkg-root ", + "Specify the vcpkg directory to use instead of current directory or tool directory"); } } diff --git a/toolsrc/src/vcpkg/vcpkgpaths.cpp b/toolsrc/src/vcpkg/vcpkgpaths.cpp index 47994660c..0f99e01d3 100644 --- a/toolsrc/src/vcpkg/vcpkgpaths.cpp +++ b/toolsrc/src/vcpkg/vcpkgpaths.cpp @@ -152,7 +152,7 @@ namespace vcpkg const std::vector& vs_toolsets = this->toolsets.get_lazy([this]() { return VisualStudio::find_toolset_instances_preferred_first(*this); }); - std::vector candidates = Util::element_pointers(vs_toolsets); + std::vector candidates = Util::fmap(vs_toolsets, [](auto&& x) { return &x; }); const auto tsv = prebuildinfo.platform_toolset.get(); auto vsp = prebuildinfo.visual_studio_path.get(); if (!vsp && !default_vs_path.empty()) diff --git a/toolsrc/src/vcpkg/visualstudio.cpp b/toolsrc/src/vcpkg/visualstudio.cpp index d2fccc716..df3c70de2 100644 --- a/toolsrc/src/vcpkg/visualstudio.cpp +++ b/toolsrc/src/vcpkg/visualstudio.cpp @@ -3,7 +3,9 @@ #if defined(_WIN32) #include -#include +#include +#include +#include #include #include @@ -90,11 +92,11 @@ namespace vcpkg::VisualStudio code_and_output.output); const auto instance_entries = - StringRange::find_all_enclosed(code_and_output.output, "", ""); - for (const StringRange& instance : instance_entries) + StringView::find_all_enclosed(code_and_output.output, "", ""); + for (const StringView& instance : instance_entries) { auto maybe_is_prerelease = - StringRange::find_at_most_one_enclosed(instance, "", ""); + StringView::find_at_most_one_enclosed(instance, "", ""); VisualStudioInstance::ReleaseType release_type = VisualStudioInstance::ReleaseType::LEGACY; if (const auto p = maybe_is_prerelease.get()) @@ -109,9 +111,9 @@ namespace vcpkg::VisualStudio } instances.emplace_back( - StringRange::find_exactly_one_enclosed(instance, "", "") + StringView::find_exactly_one_enclosed(instance, "", "") .to_string(), - StringRange::find_exactly_one_enclosed(instance, "", "") + StringView::find_exactly_one_enclosed(instance, "", "") .to_string(), release_type); } @@ -326,23 +328,23 @@ namespace vcpkg::VisualStudio if (!excluded_toolsets.empty()) { - System::println( + System::print2( System::Color::warning, - "Warning: The following VS instances are excluded because the English language pack is unavailable."); + "Warning: The following VS instances are excluded because the English language pack is unavailable.\n"); for (const Toolset& toolset : excluded_toolsets) { - System::println(" %s", toolset.visual_studio_root_path.u8string()); + System::print2(" ", toolset.visual_studio_root_path.u8string(), '\n'); } - System::println(System::Color::warning, "Please install the English language pack."); + System::print2(System::Color::warning, "Please install the English language pack.\n"); } if (found_toolsets.empty()) { - System::println(System::Color::error, "Could not locate a complete toolset."); - System::println("The following paths were examined:"); + System::print2(System::Color::error, "Could not locate a complete toolset.\n"); + System::print2("The following paths were examined:\n"); for (const fs::path& path : paths_examined) { - System::println(" %s", path.u8string()); + System::print2(" ", path.u8string(), '\n'); } Checks::exit_fail(VCPKG_LINE_INFO); } diff --git a/toolsrc/vcpkglib/vcpkglib.vcxproj b/toolsrc/vcpkglib/vcpkglib.vcxproj index 8df9b5b9d..a64eb42fd 100644 --- a/toolsrc/vcpkglib/vcpkglib.vcxproj +++ b/toolsrc/vcpkglib/vcpkglib.vcxproj @@ -210,11 +210,11 @@ - - + + diff --git a/toolsrc/vcpkglib/vcpkglib.vcxproj.filters b/toolsrc/vcpkglib/vcpkglib.vcxproj.filters index 3e0ccd885..36840c509 100644 --- a/toolsrc/vcpkglib/vcpkglib.vcxproj.filters +++ b/toolsrc/vcpkglib/vcpkglib.vcxproj.filters @@ -177,9 +177,6 @@ Source Files\vcpkg\base - - Source Files\vcpkg\base - Source Files\vcpkg\base @@ -201,9 +198,6 @@ Source Files\vcpkg - - Source Files\vcpkg\base - Source Files\vcpkg @@ -216,6 +210,12 @@ Source Files\vcpkg + + Source Files\vcpkg\base + + + Source Files\vcpkg\base +