aboutsummaryrefslogtreecommitdiff
path: root/toolsrc/include
diff options
context:
space:
mode:
authorCurtis J Bezault <curtbezault@gmail.com>2019-08-09 11:59:32 -0400
committerGitHub <noreply@github.com>2019-08-09 11:59:32 -0400
commitc4f1a91ef245ed3e44ea11f13040a77453126165 (patch)
tree3e6c99d970fe8a5fcd1551bbcbf9fde4f0b0a3a4 /toolsrc/include
parent9da7c5c99ee42e382895dbd0dafdd29beaa61075 (diff)
parent743e168ef5c7705e44d1d5cab5b9cca22328345e (diff)
downloadvcpkg-c4f1a91ef245ed3e44ea11f13040a77453126165.tar.gz
vcpkg-c4f1a91ef245ed3e44ea11f13040a77453126165.zip
Merge branch 'master' into external_file_abi
Diffstat (limited to 'toolsrc/include')
-rw-r--r--toolsrc/include/pch.h12
-rw-r--r--toolsrc/include/vcpkg-test/util.h78
-rw-r--r--toolsrc/include/vcpkg/base/files.h108
-rw-r--r--toolsrc/include/vcpkg/base/strings.h4
-rw-r--r--toolsrc/include/vcpkg/base/util.h6
-rw-r--r--toolsrc/include/vcpkg/base/work_queue.h218
-rw-r--r--toolsrc/include/vcpkg/binaryparagraph.h3
-rw-r--r--toolsrc/include/vcpkg/build.h4
-rw-r--r--toolsrc/include/vcpkg/dependencies.h11
-rw-r--r--toolsrc/include/vcpkg/logicexpression.h10
-rw-r--r--toolsrc/include/vcpkg/paragraphs.h1
-rw-r--r--toolsrc/include/vcpkg/pragmas.h11
-rw-r--r--toolsrc/include/vcpkg/sourceparagraph.h6
-rw-r--r--toolsrc/include/vcpkg/statusparagraph.h2
-rw-r--r--toolsrc/include/vcpkg/vcpkgpaths.h2
15 files changed, 254 insertions, 222 deletions
diff --git a/toolsrc/include/pch.h b/toolsrc/include/pch.h
index 15ec25e76..ce2a7c9c5 100644
--- a/toolsrc/include/pch.h
+++ b/toolsrc/include/pch.h
@@ -1,14 +1,6 @@
#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
+#include <vcpkg/pragmas.h>
#if defined(_WIN32)
#define NOMINMAX
@@ -38,8 +30,8 @@
#include <cstddef>
#include <cstdint>
#define _SILENCE_EXPERIMENTAL_FILESYSTEM_DEPRECATION_WARNING
-#include <experimental/filesystem>
#include <cstring>
+#include <experimental/filesystem>
#include <fstream>
#include <functional>
#include <iomanip>
diff --git a/toolsrc/include/vcpkg-test/util.h b/toolsrc/include/vcpkg-test/util.h
index fa650abc8..8a458a3e5 100644
--- a/toolsrc/include/vcpkg-test/util.h
+++ b/toolsrc/include/vcpkg-test/util.h
@@ -1,42 +1,68 @@
+#include <vcpkg-test/catch.h>
+#include <vcpkg/pragmas.h>
+
#include <vcpkg/base/files.h>
#include <vcpkg/statusparagraph.h>
#include <memory>
-namespace vcpkg::Test {
+#define CHECK_EC(ec) \
+ do \
+ { \
+ if (ec) \
+ { \
+ FAIL(ec.message()); \
+ } \
+ } while (0)
-std::unique_ptr<vcpkg::StatusParagraph> make_status_pgh(const char* name,
- const char* depends = "",
- const char* default_features = "",
- const char* triplet = "x86-windows");
+namespace vcpkg::Test
+{
+ std::unique_ptr<vcpkg::StatusParagraph> make_status_pgh(const char* name,
+ const char* depends = "",
+ const char* default_features = "",
+ const char* triplet = "x86-windows");
-std::unique_ptr<vcpkg::StatusParagraph> make_status_feature_pgh(const char* name,
- const char* feature,
- const char* depends = "",
- const char* triplet = "x86-windows");
+ std::unique_ptr<vcpkg::StatusParagraph> make_status_feature_pgh(const char* name,
+ const char* feature,
+ const char* depends = "",
+ const char* triplet = "x86-windows");
-vcpkg::PackageSpec unsafe_pspec(std::string name, vcpkg::Triplet t = vcpkg::Triplet::X86_WINDOWS);
+ vcpkg::PackageSpec unsafe_pspec(std::string name, vcpkg::Triplet t = vcpkg::Triplet::X86_WINDOWS);
-template<class T, class S>
-T&& unwrap(vcpkg::ExpectedT<T, S>&& p)
-{
- REQUIRE(p.has_value());
- return std::move(*p.get());
-}
+ template<class T, class S>
+ T&& unwrap(vcpkg::ExpectedT<T, S>&& p)
+ {
+ REQUIRE(p.has_value());
+ return std::move(*p.get());
+ }
-template<class T>
-T&& unwrap(vcpkg::Optional<T>&& opt)
-{
- REQUIRE(opt.has_value());
- return std::move(*opt.get());
-}
+ template<class T>
+ T&& unwrap(vcpkg::Optional<T>&& opt)
+ {
+ REQUIRE(opt.has_value());
+ return std::move(*opt.get());
+ }
+
+ struct AllowSymlinks
+ {
+ enum Tag : bool
+ {
+ No = false,
+ Yes = true,
+ } tag;
+
+ constexpr AllowSymlinks(Tag tag) noexcept : tag(tag) {}
+
+ constexpr explicit AllowSymlinks(bool b) noexcept : tag(b ? Yes : No) {}
-extern const bool SYMLINKS_ALLOWED;
+ constexpr operator bool() const noexcept { return tag == Yes; }
+ };
-extern const fs::path TEMPORARY_DIRECTORY;
+ AllowSymlinks can_create_symlinks() noexcept;
-void create_symlink(const fs::path& file, const fs::path& target, std::error_code& ec);
+ const fs::path& base_temporary_directory() noexcept;
-void create_directory_symlink(const fs::path& file, const fs::path& target, std::error_code& ec);
+ void create_symlink(const fs::path& file, const fs::path& target, std::error_code& ec);
+ void create_directory_symlink(const fs::path& file, const fs::path& target, std::error_code& ec);
}
diff --git a/toolsrc/include/vcpkg/base/files.h b/toolsrc/include/vcpkg/base/files.h
index a5e04db25..19e4f78fd 100644
--- a/toolsrc/include/vcpkg/base/files.h
+++ b/toolsrc/include/vcpkg/base/files.h
@@ -10,47 +10,125 @@ namespace fs
namespace stdfs = std::experimental::filesystem;
using stdfs::copy_options;
- using stdfs::file_status;
- using stdfs::file_type;
using stdfs::path;
using stdfs::perms;
using stdfs::u8path;
+#if defined(_WIN32)
+ enum class file_type
+ {
+ none = 0,
+ not_found = -1,
+ regular = 1,
+ directory = 2,
+ symlink = 3,
+ block = 4,
+ character = 5,
+ fifo = 6,
+ socket = 7,
+ unknown = 8,
+ // also stands for a junction
+ directory_symlink = 42
+ };
+
+ struct file_status
+ {
+ explicit file_status(file_type type = file_type::none, perms permissions = perms::unknown) noexcept
+ : m_type(type), m_permissions(permissions)
+ {
+ }
+
+ file_type type() const noexcept { return m_type; }
+ void type(file_type type) noexcept { m_type = type; }
+
+ perms permissions() const noexcept { return m_permissions; }
+ void permissions(perms perm) noexcept { m_permissions = perm; }
+
+ private:
+ file_type m_type;
+ perms m_permissions;
+ };
+
+#else
+
+ using stdfs::file_status;
+ using stdfs::file_type;
+
+#endif
+
/*
std::experimental::filesystem's file_status and file_type are broken in
the presence of symlinks -- a symlink is treated as the object it points
to for `symlink_status` and `symlink_type`
*/
- using stdfs::status;
-
// we want to poison ADL with these niebloids
namespace detail
{
+ struct status_t
+ {
+ file_status operator()(const path& p, std::error_code& ec) const noexcept;
+ file_status operator()(vcpkg::LineInfo li, const path& p) const noexcept;
+ file_status operator()(const path& p) const;
+ };
struct symlink_status_t
{
file_status operator()(const path& p, std::error_code& ec) const noexcept;
- file_status operator()(const path& p, vcpkg::LineInfo li) const noexcept;
+ file_status operator()(vcpkg::LineInfo li, const path& p) const noexcept;
};
struct is_symlink_t
{
- inline bool operator()(file_status s) const { return stdfs::is_symlink(s); }
+ bool operator()(file_status s) const
+ {
+#if defined(_WIN32)
+ return s.type() == file_type::directory_symlink || s.type() == file_type::symlink;
+#else
+ return stdfs::is_symlink(s);
+#endif
+ }
};
struct is_regular_file_t
{
- inline bool operator()(file_status s) const { return stdfs::is_regular_file(s); }
+ inline bool operator()(file_status s) const
+ {
+#if defined(_WIN32)
+ return s.type() == file_type::regular;
+#else
+ return stdfs::is_regular_file(s);
+#endif
+ }
};
struct is_directory_t
{
- inline bool operator()(file_status s) const { return stdfs::is_directory(s); }
+ inline bool operator()(file_status s) const
+ {
+#if defined(_WIN32)
+ return s.type() == file_type::directory;
+#else
+ return stdfs::is_directory(s);
+#endif
+ }
+ };
+ struct exists_t
+ {
+ inline bool operator()(file_status s) const
+ {
+#if defined(_WIN32)
+ return s.type() != file_type::not_found && s.type() != file_type::none;
+#else
+ return stdfs::exists(s);
+#endif
+ }
};
}
+ constexpr detail::status_t status{};
constexpr detail::symlink_status_t symlink_status{};
constexpr detail::is_symlink_t is_symlink{};
constexpr detail::is_regular_file_t is_regular_file{};
constexpr detail::is_directory_t is_directory{};
+ constexpr detail::exists_t exists{};
}
/*
@@ -59,12 +137,14 @@ namespace fs
Therefore, put `symlink_status` in the global namespace, so that they get
our symlink_status.
- We also want to poison the ADL on is_regular_file and is_directory, because
+ We also want to poison the ADL on the other functions, because
we don't want people calling these functions on paths
*/
+using fs::exists;
using fs::is_directory;
using fs::is_regular_file;
using fs::is_symlink;
+using fs::status;
using fs::symlink_status;
namespace vcpkg::Files
@@ -92,9 +172,13 @@ namespace vcpkg::Files
bool remove(const fs::path& path, LineInfo linfo);
virtual bool remove(const fs::path& path, std::error_code& ec) = 0;
- virtual std::uintmax_t remove_all(const fs::path& path, std::error_code& ec, fs::path& failure_point) = 0;
- std::uintmax_t remove_all(const fs::path& path, LineInfo li);
- virtual bool exists(const fs::path& path) const = 0;
+ virtual void remove_all(const fs::path& path, std::error_code& ec, fs::path& failure_point) = 0;
+ void remove_all(const fs::path& path, LineInfo li);
+ bool exists(const fs::path& path, std::error_code& ec) const;
+ bool exists(LineInfo li, const fs::path& path) const;
+ // this should probably not exist, but would require a pass through of
+ // existing code to fix
+ bool exists(const fs::path& path) const;
virtual bool is_directory(const fs::path& path) const = 0;
virtual bool is_regular_file(const fs::path& path) const = 0;
virtual bool is_empty(const fs::path& path) const = 0;
diff --git a/toolsrc/include/vcpkg/base/strings.h b/toolsrc/include/vcpkg/base/strings.h
index d7de9b0b2..dde4e9693 100644
--- a/toolsrc/include/vcpkg/base/strings.h
+++ b/toolsrc/include/vcpkg/base/strings.h
@@ -185,8 +185,6 @@ namespace vcpkg::Strings
bool contains(StringView haystack, StringView needle);
- // base 32 encoding, since base64 encoding requires lowercase letters,
- // which are not distinct from uppercase letters on macOS or Windows filesystems.
- // follows RFC 4648
+ // base 32 encoding, following IETC RFC 4648
std::string b32_encode(std::uint64_t x) noexcept;
}
diff --git a/toolsrc/include/vcpkg/base/util.h b/toolsrc/include/vcpkg/base/util.h
index e629ef0b2..90c947aa9 100644
--- a/toolsrc/include/vcpkg/base/util.h
+++ b/toolsrc/include/vcpkg/base/util.h
@@ -3,19 +3,19 @@
#include <algorithm>
#include <map>
#include <mutex>
+#include <type_traits>
#include <unordered_map>
#include <utility>
#include <vector>
-#include <type_traits>
namespace vcpkg::Util
{
- template <class T>
+ template<class T>
constexpr std::add_const_t<T>& as_const(T& t) noexcept
{
return t;
}
- template <class T>
+ template<class T>
void as_const(const T&&) = delete;
template<class Container>
diff --git a/toolsrc/include/vcpkg/base/work_queue.h b/toolsrc/include/vcpkg/base/work_queue.h
index 70142e110..a60613a3c 100644
--- a/toolsrc/include/vcpkg/base/work_queue.h
+++ b/toolsrc/include/vcpkg/base/work_queue.h
@@ -1,108 +1,46 @@
#pragma once
+#include <vcpkg/base/checks.h>
+
#include <condition_variable>
#include <memory>
-#include <queue>
+#include <vector>
namespace vcpkg
{
- template<class Action, class ThreadLocalData>
- struct WorkQueue;
-
- namespace detail
- {
- // for SFINAE purposes, keep out of the class
- template<class Action, class ThreadLocalData>
- auto call_moved_action(Action& action,
- const WorkQueue<Action, ThreadLocalData>& work_queue,
- ThreadLocalData& tld) -> decltype(static_cast<void>(std::move(action)(tld, work_queue)))
- {
- std::move(action)(tld, work_queue);
- }
-
- template<class Action, class ThreadLocalData>
- auto call_moved_action(Action& action, const WorkQueue<Action, ThreadLocalData>&, ThreadLocalData& tld)
- -> decltype(static_cast<void>(std::move(action)(tld)))
- {
- std::move(action)(tld);
- }
- }
-
- template<class Action, class ThreadLocalData>
+ template<class Action>
struct WorkQueue
{
- template<class F>
- WorkQueue(std::uint16_t num_threads, LineInfo li, const F& tld_init) noexcept
- {
- m_line_info = li;
-
- set_unjoined_workers(num_threads);
- m_threads.reserve(num_threads);
- for (std::size_t i = 0; i < num_threads; ++i)
- {
- m_threads.push_back(std::thread(Worker{this, tld_init()}));
- }
- }
-
- WorkQueue(WorkQueue const&) = delete;
- WorkQueue(WorkQueue&&) = delete;
+ WorkQueue(LineInfo li) : m_line_info(li) {}
+ WorkQueue(const WorkQueue&) = delete;
~WorkQueue()
{
- auto lck = std::unique_lock<std::mutex>(m_mutex);
- if (!is_joined(m_state))
- {
- Checks::exit_with_message(m_line_info, "Failed to call join() on a WorkQueue that was destroyed");
- }
- }
-
- // should only be called once; anything else is an error
- void run(LineInfo li)
- {
- // this should _not_ be locked before `run()` is called; however, we
- // want to terminate if someone screws up, rather than cause UB
- auto lck = std::unique_lock<std::mutex>(m_mutex);
-
- if (m_state != State::BeforeRun)
+ auto lck = std::unique_lock<std::mutex>(m_mutex, std::try_to_lock);
+ /*
+ if we don't own the lock, there isn't much we can do
+ it is likely a spurious failure
+ */
+ if (lck && m_running_workers != 0)
{
- Checks::exit_with_message(li, "Attempted to run() twice");
+ Checks::exit_with_message(
+ m_line_info, "Internal error -- outstanding workers (%u) at destruct point", m_running_workers);
}
-
- m_state = State::Running;
}
- // runs all remaining tasks, and blocks on their finishing
- // if this is called in an existing task, _will block forever_
- // DO NOT DO THAT
- // thread-unsafe
- void join(LineInfo li)
+ template<class F>
+ void run_and_join(unsigned num_threads, const F& tld_init) noexcept
{
- {
- auto lck = std::unique_lock<std::mutex>(m_mutex);
- if (is_joined(m_state))
- {
- Checks::exit_with_message(li, "Attempted to call join() more than once");
- }
- else if (m_state == State::Terminated)
- {
- m_state = State::TerminatedJoined;
- }
- else
- {
- m_state = State::Joined;
- }
- }
+ if (m_actions.empty()) return;
- while (unjoined_workers())
+ std::vector<std::thread> threads;
+ threads.reserve(num_threads);
+ for (unsigned i = 0; i < num_threads; ++i)
{
- if (!running_workers())
- {
- m_cv.notify_one();
- }
+ threads.emplace_back(Worker<decltype(tld_init())>{this, tld_init()});
}
- // wait for all threads to join
- for (auto& thrd : m_threads)
+ for (auto& thrd : threads)
{
thrd.join();
}
@@ -111,18 +49,12 @@ namespace vcpkg
// useful in the case of errors
// doesn't stop any existing running tasks
// returns immediately, so that one can call this in a task
- void terminate() const
+ void cancel() const
{
{
- auto lck = std::unique_lock<std::mutex>(m_mutex);
- if (is_joined(m_state))
- {
- m_state = State::TerminatedJoined;
- }
- else
- {
- m_state = State::Terminated;
- }
+ auto lck = std::lock_guard<std::mutex>(m_mutex);
+ m_cancelled = true;
+ m_actions.clear();
}
m_cv.notify_all();
}
@@ -130,15 +62,16 @@ namespace vcpkg
void enqueue_action(Action a) const
{
{
- auto lck = std::unique_lock<std::mutex>(m_mutex);
- m_actions.push_back(std::move(a));
+ auto lck = std::lock_guard<std::mutex>(m_mutex);
+ if (m_cancelled) return;
- if (m_state == State::BeforeRun) return;
+ m_actions.push_back(std::move(a));
}
m_cv.notify_one();
}
private:
+ template<class ThreadLocalData>
struct Worker
{
const WorkQueue* work_queue;
@@ -146,85 +79,62 @@ namespace vcpkg
void operator()()
{
- // unlocked when waiting, or when in the action
- // locked otherwise
auto lck = std::unique_lock<std::mutex>(work_queue->m_mutex);
-
- work_queue->m_cv.wait(lck, [&] { return work_queue->m_state != State::BeforeRun; });
-
- work_queue->increment_running_workers();
for (;;)
{
- const auto state = work_queue->m_state;
-
- if (is_terminated(state))
+ const auto& w = *work_queue;
+ work_queue->m_cv.wait(lck, [&w] {
+ if (w.m_cancelled)
+ return true;
+ else if (!w.m_actions.empty())
+ return true;
+ else if (w.m_running_workers == 0)
+ return true;
+ else
+ return false;
+ });
+
+ if (work_queue->m_cancelled || work_queue->m_actions.empty())
{
+ /*
+ if we've been cancelled, or if the work queue is empty
+ and there are no other workers, we want to return
+ immediately; we don't check for the latter condition
+ since if we're at this point, then either the queue
+ is not empty, or there are no other workers, or both.
+ We can't have an empty queue, and other workers, or
+ we would still be in the wait.
+ */
break;
}
- if (work_queue->m_actions.empty())
- {
- if (state == State::Running || work_queue->running_workers() > 1)
- {
- work_queue->decrement_running_workers();
- work_queue->m_cv.wait(lck);
- work_queue->increment_running_workers();
- continue;
- }
-
- // the queue is joining, and we are the only worker running
- // no more work!
- break;
- }
+ ++work_queue->m_running_workers;
- Action action = std::move(work_queue->m_actions.back());
+ auto action = std::move(work_queue->m_actions.back());
work_queue->m_actions.pop_back();
lck.unlock();
work_queue->m_cv.notify_one();
- detail::call_moved_action(action, *work_queue, tld);
+ std::move(action)(tld, *work_queue);
lck.lock();
- }
- work_queue->decrement_running_workers();
- work_queue->decrement_unjoined_workers();
+ const auto after = --work_queue->m_running_workers;
+ if (work_queue->m_actions.empty() && after == 0)
+ {
+ work_queue->m_cv.notify_all();
+ return;
+ }
+ }
}
};
- enum class State : std::int16_t
- {
- // can only exist upon construction
- BeforeRun = -1,
-
- Running,
- Joined,
- Terminated,
- TerminatedJoined,
- };
-
- static bool is_terminated(State st) { return st == State::Terminated || st == State::TerminatedJoined; }
-
- static bool is_joined(State st) { return st == State::Joined || st == State::TerminatedJoined; }
-
mutable std::mutex m_mutex{};
// these are all under m_mutex
- mutable State m_state = State::BeforeRun;
+ mutable bool m_cancelled = false;
mutable std::vector<Action> m_actions{};
mutable std::condition_variable m_cv{};
+ mutable unsigned long m_running_workers = 0;
- mutable std::atomic<std::uint32_t> m_workers;
- // = unjoined_workers << 16 | running_workers
-
- void set_unjoined_workers(std::uint16_t threads) { m_workers = std::uint32_t(threads) << 16; }
- void decrement_unjoined_workers() const { m_workers -= 1 << 16; }
-
- std::uint16_t unjoined_workers() const { return std::uint16_t(m_workers >> 16); }
-
- void increment_running_workers() const { ++m_workers; }
- void decrement_running_workers() const { --m_workers; }
- std::uint16_t running_workers() const { return std::uint16_t(m_workers); }
-
- std::vector<std::thread> m_threads{};
LineInfo m_line_info;
};
}
diff --git a/toolsrc/include/vcpkg/binaryparagraph.h b/toolsrc/include/vcpkg/binaryparagraph.h
index d75e4abb1..a68fcfb36 100644
--- a/toolsrc/include/vcpkg/binaryparagraph.h
+++ b/toolsrc/include/vcpkg/binaryparagraph.h
@@ -1,6 +1,7 @@
#pragma once
#include <vcpkg/packagespec.h>
+#include <vcpkg/parse.h>
#include <vcpkg/sourceparagraph.h>
#include <map>
@@ -20,7 +21,7 @@ namespace vcpkg
struct BinaryParagraph
{
BinaryParagraph();
- explicit BinaryParagraph(std::unordered_map<std::string, std::string> fields);
+ explicit BinaryParagraph(Parse::RawParagraph fields);
BinaryParagraph(const SourceParagraph& spgh, const Triplet& triplet, const std::string& abi_tag);
BinaryParagraph(const SourceParagraph& spgh, const FeatureParagraph& fpgh, const Triplet& triplet);
diff --git a/toolsrc/include/vcpkg/build.h b/toolsrc/include/vcpkg/build.h
index 2d5e18a43..c393d989b 100644
--- a/toolsrc/include/vcpkg/build.h
+++ b/toolsrc/include/vcpkg/build.h
@@ -126,8 +126,8 @@ namespace vcpkg::Build
/// Runs the triplet file in a "capture" mode to create a PreBuildInfo
/// </summary>
static PreBuildInfo from_triplet_file(const VcpkgPaths& paths,
- const Triplet& triplet,
- Optional<const SourceControlFileLocation&> port = nullopt);
+ const Triplet& triplet,
+ Optional<const SourceControlFileLocation&> port = nullopt);
std::string triplet_abi_tag;
std::string target_architecture;
diff --git a/toolsrc/include/vcpkg/dependencies.h b/toolsrc/include/vcpkg/dependencies.h
index 964158026..e9018b1b8 100644
--- a/toolsrc/include/vcpkg/dependencies.h
+++ b/toolsrc/include/vcpkg/dependencies.h
@@ -145,7 +145,7 @@ namespace vcpkg::Dependencies
struct PathsPortFileProvider : Util::ResourceBase, PortFileProvider
{
- explicit PathsPortFileProvider(const vcpkg::VcpkgPaths& paths,
+ explicit PathsPortFileProvider(const vcpkg::VcpkgPaths& paths,
const std::vector<std::string>* ports_dirs_paths);
Optional<const SourceControlFileLocation&> get_control_file(const std::string& src_name) const override;
std::vector<const SourceControlFileLocation*> load_all_control_files() const override;
@@ -186,9 +186,10 @@ namespace vcpkg::Dependencies
std::vector<ExportPlanAction> create_export_plan(const std::vector<PackageSpec>& specs,
const StatusParagraphs& status_db);
- std::vector<AnyAction> create_feature_install_plan(const std::unordered_map<std::string, SourceControlFileLocation>& map,
- const std::vector<FeatureSpec>& specs,
- const StatusParagraphs& status_db);
+ std::vector<AnyAction> create_feature_install_plan(
+ const std::unordered_map<std::string, SourceControlFileLocation>& map,
+ const std::vector<FeatureSpec>& specs,
+ const StatusParagraphs& status_db);
/// <summary>Figure out which actions are required to install features specifications in `specs`.</summary>
/// <param name="provider">Contains the ports of the current environment.</param>
@@ -199,7 +200,7 @@ namespace vcpkg::Dependencies
const StatusParagraphs& status_db,
const CreateInstallPlanOptions& options = {});
- void print_plan(const std::vector<AnyAction>& action_plan,
+ void print_plan(const std::vector<AnyAction>& action_plan,
const bool is_recursive = true,
const fs::path& default_ports_dir = "");
}
diff --git a/toolsrc/include/vcpkg/logicexpression.h b/toolsrc/include/vcpkg/logicexpression.h
new file mode 100644
index 000000000..8795971b9
--- /dev/null
+++ b/toolsrc/include/vcpkg/logicexpression.h
@@ -0,0 +1,10 @@
+#pragma once
+
+#include <string>
+
+namespace vcpkg
+{
+ // Evaluate simple vcpkg logic expressions. An identifier in the expression is considered 'true'
+ // if it is a substring of the evaluation_context (typically the name of the triplet)
+ bool evaluate_expression(const std::string& expression, const std::string& evaluation_context);
+} \ No newline at end of file
diff --git a/toolsrc/include/vcpkg/paragraphs.h b/toolsrc/include/vcpkg/paragraphs.h
index 56f09387a..7e2410aef 100644
--- a/toolsrc/include/vcpkg/paragraphs.h
+++ b/toolsrc/include/vcpkg/paragraphs.h
@@ -12,7 +12,6 @@ namespace vcpkg::Paragraphs
Expected<RawParagraph> get_single_paragraph(const Files::Filesystem& fs, const fs::path& control_path);
Expected<std::vector<RawParagraph>> get_paragraphs(const Files::Filesystem& fs, const fs::path& control_path);
- Expected<RawParagraph> parse_single_paragraph(const std::string& str);
Expected<std::vector<RawParagraph>> parse_paragraphs(const std::string& str);
Parse::ParseExpected<SourceControlFile> try_load_port(const Files::Filesystem& fs, const fs::path& control_path);
diff --git a/toolsrc/include/vcpkg/pragmas.h b/toolsrc/include/vcpkg/pragmas.h
new file mode 100644
index 000000000..fa1039bce
--- /dev/null
+++ b/toolsrc/include/vcpkg/pragmas.h
@@ -0,0 +1,11 @@
+#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
diff --git a/toolsrc/include/vcpkg/sourceparagraph.h b/toolsrc/include/vcpkg/sourceparagraph.h
index 9fbd83475..95347770a 100644
--- a/toolsrc/include/vcpkg/sourceparagraph.h
+++ b/toolsrc/include/vcpkg/sourceparagraph.h
@@ -23,8 +23,7 @@ namespace vcpkg
std::vector<std::string> filter_dependencies(const std::vector<Dependency>& deps, const Triplet& t);
std::vector<FeatureSpec> filter_dependencies_to_specs(const std::vector<Dependency>& deps, const Triplet& t);
- std::vector<Features> filter_dependencies_to_features(const std::vector<vcpkg::Dependency>& deps,
- const Triplet& t);
+ std::vector<Features> filter_dependencies_to_features(const std::vector<vcpkg::Dependency>& deps, const Triplet& t);
// zlib[uwp] becomes Dependency{"zlib", "uwp"}
std::vector<Dependency> expand_qualified_dependencies(const std::vector<std::string>& depends);
@@ -71,7 +70,8 @@ namespace vcpkg
};
/// <summary>
- /// Full metadata of a package: core and other features. As well as the location the SourceControlFile was loaded from.
+ /// Full metadata of a package: core and other features. As well as the location the SourceControlFile was loaded
+ /// from.
/// </summary>
struct SourceControlFileLocation
{
diff --git a/toolsrc/include/vcpkg/statusparagraph.h b/toolsrc/include/vcpkg/statusparagraph.h
index e79c946cc..6e832fe2f 100644
--- a/toolsrc/include/vcpkg/statusparagraph.h
+++ b/toolsrc/include/vcpkg/statusparagraph.h
@@ -30,7 +30,7 @@ namespace vcpkg
struct StatusParagraph
{
StatusParagraph() noexcept;
- explicit StatusParagraph(std::unordered_map<std::string, std::string>&& fields);
+ explicit StatusParagraph(Parse::RawParagraph&& fields);
bool is_installed() const { return want == Want::INSTALL && state == InstallState::INSTALLED; }
diff --git a/toolsrc/include/vcpkg/vcpkgpaths.h b/toolsrc/include/vcpkg/vcpkgpaths.h
index ce442858b..8107b8201 100644
--- a/toolsrc/include/vcpkg/vcpkgpaths.h
+++ b/toolsrc/include/vcpkg/vcpkgpaths.h
@@ -55,7 +55,7 @@ namespace vcpkg
fs::path package_dir(const PackageSpec& spec) const;
fs::path build_info_file_path(const PackageSpec& spec) const;
fs::path listfile_path(const BinaryParagraph& pgh) const;
-
+
bool is_valid_triplet(const Triplet& t) const;
const std::vector<std::string>& get_available_triplets() const;
const fs::path get_triplet_file_path(const Triplet& triplet) const;