aboutsummaryrefslogtreecommitdiff
path: root/toolsrc/include
diff options
context:
space:
mode:
authorRobert Schumacher <roschuma@microsoft.com>2020-02-07 11:24:35 -0800
committerGitHub <noreply@github.com>2020-02-07 11:24:35 -0800
commit8db6db5dac70c25b04cd4dd84392484dee822fbe (patch)
tree4734de271f966ff4b9a913b15c1b7b537ecd1a8d /toolsrc/include
parent2873f07823df192ba55693d200850669eabe332c (diff)
downloadvcpkg-8db6db5dac70c25b04cd4dd84392484dee822fbe.tar.gz
vcpkg-8db6db5dac70c25b04cd4dd84392484dee822fbe.zip
[vcpkg] Further parser improvements (#9895)
* [vcpkg] Consolidate several internal parsers together (packagespecs + logicexpression + control) and enhance error messages * [vcpkg] Migrate Build-Depends parsing to new framework * [vcpkg] Fix tests. Re-enable underscores in feature names due to libwebp[vwebp_sdl] -- todo: rename this feature and remove underscores.
Diffstat (limited to 'toolsrc/include')
-rw-r--r--toolsrc/include/vcpkg-test/mockcmakevarprovider.h4
-rw-r--r--toolsrc/include/vcpkg-test/util.h4
-rw-r--r--toolsrc/include/vcpkg/base/expected.h105
-rw-r--r--toolsrc/include/vcpkg/base/optional.h41
-rw-r--r--toolsrc/include/vcpkg/binaryparagraph.h6
-rw-r--r--toolsrc/include/vcpkg/build.h8
-rw-r--r--toolsrc/include/vcpkg/cmakevars.h8
-rw-r--r--toolsrc/include/vcpkg/commands.h14
-rw-r--r--toolsrc/include/vcpkg/dependencies.h2
-rw-r--r--toolsrc/include/vcpkg/export.h2
-rw-r--r--toolsrc/include/vcpkg/input.h6
-rw-r--r--toolsrc/include/vcpkg/install.h2
-rw-r--r--toolsrc/include/vcpkg/packagespec.h54
-rw-r--r--toolsrc/include/vcpkg/packagespecparseresult.h35
-rw-r--r--toolsrc/include/vcpkg/paragraphparser.h45
-rw-r--r--toolsrc/include/vcpkg/paragraphs.h10
-rw-r--r--toolsrc/include/vcpkg/parse.h147
-rw-r--r--toolsrc/include/vcpkg/portfileprovider.h8
-rw-r--r--toolsrc/include/vcpkg/remove.h2
-rw-r--r--toolsrc/include/vcpkg/sourceparagraph.h25
-rw-r--r--toolsrc/include/vcpkg/statusparagraphs.h6
-rw-r--r--toolsrc/include/vcpkg/textrowcol.h12
-rw-r--r--toolsrc/include/vcpkg/triplet.h8
-rw-r--r--toolsrc/include/vcpkg/vcpkgpaths.h6
24 files changed, 405 insertions, 155 deletions
diff --git a/toolsrc/include/vcpkg-test/mockcmakevarprovider.h b/toolsrc/include/vcpkg-test/mockcmakevarprovider.h
index 03defdcdd..21207c856 100644
--- a/toolsrc/include/vcpkg-test/mockcmakevarprovider.h
+++ b/toolsrc/include/vcpkg-test/mockcmakevarprovider.h
@@ -6,7 +6,7 @@ namespace vcpkg::Test
{
struct MockCMakeVarProvider : CMakeVars::CMakeVarProvider
{
- void load_generic_triplet_vars(const Triplet& triplet) const override { generic_triplet_vars[triplet] = {}; }
+ void load_generic_triplet_vars(Triplet triplet) const override { generic_triplet_vars[triplet] = {}; }
void load_dep_info_vars(Span<const PackageSpec> specs) const override
{
@@ -23,7 +23,7 @@ namespace vcpkg::Test
}
Optional<const std::unordered_map<std::string, std::string>&> get_generic_triplet_vars(
- const Triplet& triplet) const override;
+ Triplet triplet) const override;
Optional<const std::unordered_map<std::string, std::string>&> get_dep_info_vars(
const PackageSpec& spec) const override;
diff --git a/toolsrc/include/vcpkg-test/util.h b/toolsrc/include/vcpkg-test/util.h
index 088a39b7d..d8ecc51ea 100644
--- a/toolsrc/include/vcpkg-test/util.h
+++ b/toolsrc/include/vcpkg-test/util.h
@@ -40,7 +40,7 @@ namespace vcpkg::Test
{
std::unordered_map<std::string, SourceControlFileLocation> map;
Triplet triplet;
- PackageSpecMap(const Triplet& t = Triplet::X86_WINDOWS) noexcept : triplet(t) {}
+ PackageSpecMap(Triplet t = Triplet::X86_WINDOWS) noexcept : triplet(t) {}
PackageSpec emplace(const char* name,
const char* depends = "",
@@ -50,8 +50,6 @@ namespace vcpkg::Test
PackageSpec emplace(vcpkg::SourceControlFileLocation&& scfl);
};
- 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)
{
diff --git a/toolsrc/include/vcpkg/base/expected.h b/toolsrc/include/vcpkg/base/expected.h
index c273d71e6..2b19bad2a 100644
--- a/toolsrc/include/vcpkg/base/expected.h
+++ b/toolsrc/include/vcpkg/base/expected.h
@@ -75,6 +75,30 @@ namespace vcpkg
constexpr ExpectedLeftTag expected_left_tag;
constexpr ExpectedRightTag expected_right_tag;
+ template<class T>
+ struct ExpectedHolder
+ {
+ ExpectedHolder() = default;
+ ExpectedHolder(const T& t) : t(t) {}
+ ExpectedHolder(T&& t) : t(std::move(t)) {}
+ using pointer = T*;
+ using const_pointer = const T*;
+ T* get() { return &t; }
+ const T* get() const { return &t; }
+ T t;
+ };
+ template<class T>
+ struct ExpectedHolder<T&>
+ {
+ ExpectedHolder(T& t) : t(&t) {}
+ ExpectedHolder() : t(nullptr) {}
+ using pointer = T*;
+ using const_pointer = T*;
+ T* get() { return t; }
+ T* get() const { return t; }
+ T* t;
+ };
+
template<class T, class S>
class ExpectedT
{
@@ -87,7 +111,10 @@ namespace vcpkg
ExpectedT(S&& s, ExpectedRightTag = {}) : m_s(std::move(s)) {}
ExpectedT(const T& t, ExpectedLeftTag = {}) : m_t(t) {}
- ExpectedT(T&& t, ExpectedLeftTag = {}) : m_t(std::move(t)) {}
+ template<class = std::enable_if<!std::is_reference_v<T>>>
+ ExpectedT(T&& t, ExpectedLeftTag = {}) : m_t(std::move(t))
+ {
+ }
ExpectedT(const ExpectedT&) = default;
ExpectedT(ExpectedT&&) = default;
@@ -100,35 +127,94 @@ namespace vcpkg
T&& value_or_exit(const LineInfo& line_info) &&
{
exit_if_error(line_info);
- return std::move(this->m_t);
+ return std::move(*this->m_t.get());
}
const T& value_or_exit(const LineInfo& line_info) const&
{
exit_if_error(line_info);
- return this->m_t;
+ return *this->m_t.get();
}
const S& error() const& { return this->m_s.error(); }
S&& error() && { return std::move(this->m_s.error()); }
- const T* get() const
+ typename ExpectedHolder<T>::const_pointer get() const
{
if (!this->has_value())
{
return nullptr;
}
- return &this->m_t;
+ return this->m_t.get();
}
- T* get()
+ typename ExpectedHolder<T>::pointer get()
{
if (!this->has_value())
{
return nullptr;
}
- return &this->m_t;
+ return this->m_t.get();
+ }
+
+ template<class F>
+ using map_t = decltype(std::declval<F&>()(*std::declval<typename ExpectedHolder<T>::const_pointer>()));
+
+ template<class F, class U = map_t<F>>
+ ExpectedT<U, S> map(F f) const&
+ {
+ if (has_value())
+ {
+ return {f(*m_t.get()), expected_left_tag};
+ }
+ else
+ {
+ return {error(), expected_right_tag};
+ }
+ }
+
+ template<class F>
+ using move_map_t =
+ decltype(std::declval<F&>()(std::move(*std::declval<typename ExpectedHolder<T>::pointer>())));
+
+ template<class F, class U = move_map_t<F>>
+ ExpectedT<U, S> map(F f) &&
+ {
+ if (has_value())
+ {
+ return {f(std::move(*m_t.get())), expected_left_tag};
+ }
+ else
+ {
+ return {std::move(error()), expected_right_tag};
+ }
+ }
+
+ template<class F, class U = map_t<F>>
+ U then(F f) const&
+ {
+ if (has_value())
+ {
+ return f(*m_t.get());
+ }
+ else
+ {
+ return U{error(), expected_right_tag};
+ }
+ }
+
+ template<class F, class U = move_map_t<F>>
+ U then(F f) &&
+ {
+ if (has_value())
+ {
+ return f(std::move(*m_t.get()));
+ }
+ else
+ {
+ return U{std::move(error()), expected_right_tag};
+ }
}
private:
@@ -143,9 +229,12 @@ namespace vcpkg
}
ErrorHolder<S> m_s;
- T m_t;
+ ExpectedHolder<T> m_t;
};
template<class T>
using Expected = ExpectedT<T, std::error_code>;
+
+ template<class T>
+ using ExpectedS = ExpectedT<T, std::string>;
}
diff --git a/toolsrc/include/vcpkg/base/optional.h b/toolsrc/include/vcpkg/base/optional.h
index 2d8c126c6..fc3733ead 100644
--- a/toolsrc/include/vcpkg/base/optional.h
+++ b/toolsrc/include/vcpkg/base/optional.h
@@ -228,12 +228,21 @@ namespace vcpkg
return this->m_base.has_value() ? this->m_base.value() : static_cast<T>(std::forward<U>(default_value));
}
+ T value_or(T&& default_value) const&
+ {
+ return this->m_base.has_value() ? this->m_base.value() : static_cast<T&&>(default_value);
+ }
+
template<class U>
T value_or(U&& default_value) &&
{
return this->m_base.has_value() ? std::move(this->m_base.value())
: static_cast<T>(std::forward<U>(default_value));
}
+ T value_or(T&& default_value) &&
+ {
+ return this->m_base.has_value() ? std::move(this->m_base.value()) : static_cast<T&&>(default_value);
+ }
typename std::add_pointer<const T>::type get() const
{
@@ -242,6 +251,38 @@ namespace vcpkg
typename std::add_pointer<T>::type get() { return this->m_base.has_value() ? &this->m_base.value() : nullptr; }
+ template<class F>
+ using map_t = decltype(std::declval<F&>()(std::declval<const T&>()));
+
+ template<class F, class U = map_t<F>>
+ U then(F f) const&
+ {
+ if (has_value())
+ {
+ return f(this->m_base.value());
+ }
+ else
+ {
+ return nullopt;
+ }
+ }
+
+ template<class F>
+ using move_map_t = decltype(std::declval<F&>()(std::declval<T&&>()));
+
+ template<class F, class U = move_map_t<F>>
+ U then(F f) &&
+ {
+ if (has_value())
+ {
+ return f(std::move(this->m_base.value()));
+ }
+ else
+ {
+ return nullopt;
+ }
+ }
+
private:
details::OptionalStorage<T> m_base;
};
diff --git a/toolsrc/include/vcpkg/binaryparagraph.h b/toolsrc/include/vcpkg/binaryparagraph.h
index 223a1fb86..05c42dee4 100644
--- a/toolsrc/include/vcpkg/binaryparagraph.h
+++ b/toolsrc/include/vcpkg/binaryparagraph.h
@@ -1,7 +1,7 @@
#pragma once
#include <vcpkg/packagespec.h>
-#include <vcpkg/parse.h>
+#include <vcpkg/paragraphparser.h>
#include <vcpkg/sourceparagraph.h>
namespace vcpkg
@@ -14,12 +14,12 @@ namespace vcpkg
BinaryParagraph();
explicit BinaryParagraph(Parse::RawParagraph fields);
BinaryParagraph(const SourceParagraph& spgh,
- const Triplet& triplet,
+ Triplet triplet,
const std::string& abi_tag,
const std::vector<FeatureSpec>& deps);
BinaryParagraph(const SourceParagraph& spgh,
const FeatureParagraph& fpgh,
- const Triplet& triplet,
+ Triplet triplet,
const std::vector<FeatureSpec>& deps);
std::string displayname() const;
diff --git a/toolsrc/include/vcpkg/build.h b/toolsrc/include/vcpkg/build.h
index b7b7475ef..9d555ae25 100644
--- a/toolsrc/include/vcpkg/build.h
+++ b/toolsrc/include/vcpkg/build.h
@@ -26,7 +26,7 @@ namespace vcpkg::Build
const ParsedArguments& options,
const VcpkgPaths& paths);
- void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, const Triplet& default_triplet);
+ void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, Triplet default_triplet);
}
enum class UseHeadVersion
@@ -140,7 +140,7 @@ namespace vcpkg::Build
struct PreBuildInfo
{
PreBuildInfo(const VcpkgPaths& paths,
- const Triplet& triplet,
+ Triplet triplet,
const std::unordered_map<std::string, std::string>& cmakevars);
std::string triplet_abi_tag;
@@ -197,7 +197,7 @@ namespace vcpkg::Build
struct BuildPackageConfig
{
BuildPackageConfig(const SourceControlFileLocation& scfl,
- const Triplet& triplet,
+ Triplet triplet,
const BuildPackageOptions& build_package_options,
const CMakeVars::CMakeVarProvider& var_provider,
const std::unordered_map<std::string, std::vector<FeatureSpec>>& feature_dependencies,
@@ -217,7 +217,7 @@ namespace vcpkg::Build
const SourceControlFileLocation& scfl;
const SourceControlFile& scf;
- const Triplet& triplet;
+ Triplet triplet;
const fs::path& port_dir;
const BuildPackageOptions& build_package_options;
const CMakeVars::CMakeVarProvider& var_provider;
diff --git a/toolsrc/include/vcpkg/cmakevars.h b/toolsrc/include/vcpkg/cmakevars.h
index c634866d0..8d131d45e 100644
--- a/toolsrc/include/vcpkg/cmakevars.h
+++ b/toolsrc/include/vcpkg/cmakevars.h
@@ -11,7 +11,7 @@ namespace vcpkg::CMakeVars
struct CMakeVarProvider
{
virtual Optional<const std::unordered_map<std::string, std::string>&> get_generic_triplet_vars(
- const Triplet& triplet) const = 0;
+ Triplet triplet) const = 0;
virtual Optional<const std::unordered_map<std::string, std::string>&> get_dep_info_vars(
const PackageSpec& spec) const = 0;
@@ -19,7 +19,7 @@ namespace vcpkg::CMakeVars
virtual Optional<const std::unordered_map<std::string, std::string>&> get_tag_vars(
const PackageSpec& spec) const = 0;
- virtual void load_generic_triplet_vars(const Triplet& triplet) const = 0;
+ virtual void load_generic_triplet_vars(Triplet triplet) const = 0;
virtual void load_dep_info_vars(Span<const PackageSpec> specs) const = 0;
@@ -41,7 +41,7 @@ namespace vcpkg::CMakeVars
public:
explicit TripletCMakeVarProvider(const vcpkg::VcpkgPaths& paths) : paths(paths) {}
- void load_generic_triplet_vars(const Triplet& triplet) const override;
+ void load_generic_triplet_vars(Triplet triplet) const override;
void load_dep_info_vars(Span<const PackageSpec> specs) const override;
@@ -49,7 +49,7 @@ namespace vcpkg::CMakeVars
const PortFileProvider::PortFileProvider& port_provider) const override;
Optional<const std::unordered_map<std::string, std::string>&> get_generic_triplet_vars(
- const Triplet& triplet) const override;
+ Triplet triplet) const override;
Optional<const std::unordered_map<std::string, std::string>&> get_dep_info_vars(
const PackageSpec& spec) const override;
diff --git a/toolsrc/include/vcpkg/commands.h b/toolsrc/include/vcpkg/commands.h
index e73077e1d..9d2d0b6c6 100644
--- a/toolsrc/include/vcpkg/commands.h
+++ b/toolsrc/include/vcpkg/commands.h
@@ -12,27 +12,25 @@
namespace vcpkg::Commands
{
- using CommandTypeA = void (*)(const VcpkgCmdArguments& args,
- const VcpkgPaths& paths,
- const Triplet& default_triplet);
+ using CommandTypeA = void (*)(const VcpkgCmdArguments& args, const VcpkgPaths& paths, Triplet default_triplet);
using CommandTypeB = void (*)(const VcpkgCmdArguments& args, const VcpkgPaths& paths);
using CommandTypeC = void (*)(const VcpkgCmdArguments& args);
namespace BuildExternal
{
- void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, const Triplet& default_triplet);
+ void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, Triplet default_triplet);
}
namespace CI
{
extern const CommandStructure COMMAND_STRUCTURE;
- void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, const Triplet& default_triplet);
+ void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, Triplet default_triplet);
}
namespace Env
{
extern const CommandStructure COMMAND_STRUCTURE;
- void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, const Triplet& default_triplet);
+ void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, Triplet default_triplet);
}
namespace Create
@@ -44,7 +42,7 @@ namespace vcpkg::Commands
namespace Upgrade
{
extern const CommandStructure COMMAND_STRUCTURE;
- void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, const Triplet& default_triplet);
+ void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, Triplet default_triplet);
}
namespace Edit
@@ -56,7 +54,7 @@ namespace vcpkg::Commands
namespace DependInfo
{
extern const CommandStructure COMMAND_STRUCTURE;
- void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, const Triplet& default_triplet);
+ void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, Triplet default_triplet);
}
namespace Search
diff --git a/toolsrc/include/vcpkg/dependencies.h b/toolsrc/include/vcpkg/dependencies.h
index eb9d42b6d..1f92ee63c 100644
--- a/toolsrc/include/vcpkg/dependencies.h
+++ b/toolsrc/include/vcpkg/dependencies.h
@@ -121,7 +121,7 @@ namespace vcpkg::Dependencies
RequestType request_type;
Optional<const BinaryParagraph&> core_paragraph() const;
- std::vector<PackageSpec> dependencies(const Triplet& triplet) const;
+ std::vector<PackageSpec> dependencies(Triplet triplet) const;
private:
Optional<InstalledPackageView> m_installed_package;
diff --git a/toolsrc/include/vcpkg/export.h b/toolsrc/include/vcpkg/export.h
index eb99b4fb1..3605081e3 100644
--- a/toolsrc/include/vcpkg/export.h
+++ b/toolsrc/include/vcpkg/export.h
@@ -6,7 +6,7 @@ namespace vcpkg::Export
{
extern const CommandStructure COMMAND_STRUCTURE;
- void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, const Triplet& default_triplet);
+ void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, Triplet default_triplet);
void export_integration_files(const fs::path& raw_exported_dir_path, const VcpkgPaths& paths);
}
diff --git a/toolsrc/include/vcpkg/input.h b/toolsrc/include/vcpkg/input.h
index ef481bf52..917b5af10 100644
--- a/toolsrc/include/vcpkg/input.h
+++ b/toolsrc/include/vcpkg/input.h
@@ -5,11 +5,11 @@
namespace vcpkg::Input
{
PackageSpec check_and_get_package_spec(std::string&& spec_string,
- const Triplet& default_triplet,
+ Triplet default_triplet,
CStringView example_text);
FullPackageSpec check_and_get_full_package_spec(std::string&& spec_string,
- const Triplet& default_triplet,
+ Triplet default_triplet,
CStringView example_text);
- void check_triplet(const Triplet& t, const VcpkgPaths& paths);
+ void check_triplet(Triplet t, const VcpkgPaths& paths);
}
diff --git a/toolsrc/include/vcpkg/install.h b/toolsrc/include/vcpkg/install.h
index e020c8653..1c42cc102 100644
--- a/toolsrc/include/vcpkg/install.h
+++ b/toolsrc/include/vcpkg/install.h
@@ -83,5 +83,5 @@ namespace vcpkg::Install
extern const CommandStructure COMMAND_STRUCTURE;
- void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, const Triplet& default_triplet);
+ void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, Triplet default_triplet);
}
diff --git a/toolsrc/include/vcpkg/packagespec.h b/toolsrc/include/vcpkg/packagespec.h
index 628352cdb..a37dc99b3 100644
--- a/toolsrc/include/vcpkg/packagespec.h
+++ b/toolsrc/include/vcpkg/packagespec.h
@@ -1,20 +1,16 @@
#pragma once
#include <vcpkg/base/expected.h>
-#include <vcpkg/packagespecparseresult.h>
+#include <vcpkg/base/optional.h>
#include <vcpkg/triplet.h>
-namespace vcpkg
+namespace vcpkg::Parse
{
- struct ParsedSpecifier
- {
- std::string name;
- std::vector<std::string> features;
- std::string triplet;
-
- static ExpectedT<ParsedSpecifier, PackageSpecParseResult> from_string(const std::string& input);
- };
+ struct ParserBase;
+}
+namespace vcpkg
+{
///
/// <summary>
/// Full specification of a package. Contains all information to reference
@@ -26,14 +22,11 @@ namespace vcpkg
PackageSpec() noexcept = default;
PackageSpec(std::string name, Triplet triplet) : m_name(std::move(name)), m_triplet(triplet) {}
- static ExpectedT<PackageSpec, PackageSpecParseResult> from_name_and_triplet(const std::string& name,
- const Triplet& triplet);
-
- static std::vector<PackageSpec> to_package_specs(const std::vector<std::string>& ports, const Triplet& triplet);
+ static std::vector<PackageSpec> to_package_specs(const std::vector<std::string>& ports, Triplet triplet);
const std::string& name() const;
- const Triplet& triplet() const;
+ Triplet triplet() const;
std::string dir() const;
@@ -64,16 +57,13 @@ namespace vcpkg
const std::string& name() const { return m_spec.name(); }
const std::string& feature() const { return m_feature; }
- const Triplet& triplet() const { return m_spec.triplet(); }
+ Triplet triplet() const { return m_spec.triplet(); }
const PackageSpec& spec() const { return m_spec; }
std::string to_string() const;
void to_string(std::string& out) const;
- static std::vector<FeatureSpec> from_strings_and_triplet(const std::vector<std::string>& depends,
- const Triplet& t);
-
bool operator<(const FeatureSpec& other) const
{
if (name() < other.name()) return true;
@@ -115,8 +105,7 @@ namespace vcpkg
std::vector<FeatureSpec> to_feature_specs(const std::vector<std::string>& default_features,
const std::vector<std::string>& all_features) const;
- static ExpectedT<FullPackageSpec, PackageSpecParseResult> from_string(const std::string& spec_as_string,
- const Triplet& default_triplet);
+ static ExpectedS<FullPackageSpec> from_string(const std::string& spec_as_string, Triplet default_triplet);
};
///
@@ -129,9 +118,30 @@ namespace vcpkg
std::string name;
std::vector<std::string> features;
- static ExpectedT<Features, PackageSpecParseResult> from_string(const std::string& input);
+ static ExpectedS<Features> from_string(const std::string& input);
+ };
+
+ struct Dependency
+ {
+ Features depend;
+ std::string qualifier;
+
+ static ExpectedS<Dependency> from_string(const std::string& input);
};
+ struct ParsedQualifiedSpecifier
+ {
+ std::string name;
+ Optional<std::vector<std::string>> features;
+ Optional<std::string> triplet;
+ Optional<std::string> qualifier;
+ };
+
+ Optional<std::string> parse_feature_name(Parse::ParserBase& parser);
+ Optional<std::string> parse_package_name(Parse::ParserBase& parser);
+ ExpectedS<ParsedQualifiedSpecifier> parse_qualified_specifier(CStringView input);
+ Optional<ParsedQualifiedSpecifier> parse_qualified_specifier(Parse::ParserBase& parser);
+
bool operator==(const PackageSpec& left, const PackageSpec& right);
bool operator!=(const PackageSpec& left, const PackageSpec& right);
}
diff --git a/toolsrc/include/vcpkg/packagespecparseresult.h b/toolsrc/include/vcpkg/packagespecparseresult.h
deleted file mode 100644
index 4c99c84c7..000000000
--- a/toolsrc/include/vcpkg/packagespecparseresult.h
+++ /dev/null
@@ -1,35 +0,0 @@
-#pragma once
-
-#include <vcpkg/base/cstringview.h>
-#include <vcpkg/base/expected.h>
-
-namespace vcpkg
-{
- enum class PackageSpecParseResult
- {
- SUCCESS = 0,
- TOO_MANY_COLONS,
- INVALID_CHARACTERS
- };
-
- void to_string(std::string& out, ::vcpkg::PackageSpecParseResult p);
-
- CStringView to_string(PackageSpecParseResult ev) noexcept;
-
- template<>
- struct ErrorHolder<PackageSpecParseResult>
- {
- ErrorHolder() noexcept : m_err(PackageSpecParseResult::SUCCESS) {}
- ErrorHolder(PackageSpecParseResult err) : m_err(err) {}
-
- bool has_error() const { return m_err != PackageSpecParseResult::SUCCESS; }
-
- const PackageSpecParseResult& error() const { return m_err; }
- PackageSpecParseResult& error() { return m_err; }
-
- CStringView to_string() const { return vcpkg::to_string(m_err); }
-
- private:
- PackageSpecParseResult m_err;
- };
-}
diff --git a/toolsrc/include/vcpkg/paragraphparser.h b/toolsrc/include/vcpkg/paragraphparser.h
new file mode 100644
index 000000000..86c3d0228
--- /dev/null
+++ b/toolsrc/include/vcpkg/paragraphparser.h
@@ -0,0 +1,45 @@
+#pragma once
+
+#include <vcpkg/base/expected.h>
+#include <vcpkg/packagespec.h>
+
+#include <memory>
+#include <string>
+#include <unordered_map>
+#include <vector>
+
+namespace vcpkg::Parse
+{
+ struct ParseControlErrorInfo
+ {
+ std::string name;
+ std::vector<std::string> missing_fields;
+ std::vector<std::string> extra_fields;
+ std::string error;
+ };
+
+ template<class P>
+ using ParseExpected = vcpkg::ExpectedT<std::unique_ptr<P>, std::unique_ptr<ParseControlErrorInfo>>;
+
+ using RawParagraph = std::unordered_map<std::string, std::string>;
+
+ struct ParagraphParser
+ {
+ ParagraphParser(RawParagraph&& fields) : fields(std::move(fields)) {}
+
+ void required_field(const std::string& fieldname, std::string& out);
+ std::string optional_field(const std::string& fieldname) const;
+ std::unique_ptr<ParseControlErrorInfo> error_info(const std::string& name) const;
+
+ private:
+ RawParagraph&& fields;
+ std::vector<std::string> missing_fields;
+ };
+
+ ExpectedS<std::vector<std::string>> parse_default_features_list(const std::string& str,
+ CStringView origin = "<unknown>");
+ ExpectedS<std::vector<ParsedQualifiedSpecifier>> parse_qualified_specifier_list(const std::string& str,
+ CStringView origin = "<unknown>");
+ ExpectedS<std::vector<Dependency>> parse_dependencies_list(const std::string& str,
+ CStringView origin = "<unknown>");
+}
diff --git a/toolsrc/include/vcpkg/paragraphs.h b/toolsrc/include/vcpkg/paragraphs.h
index 7e2410aef..cffe85af7 100644
--- a/toolsrc/include/vcpkg/paragraphs.h
+++ b/toolsrc/include/vcpkg/paragraphs.h
@@ -1,7 +1,7 @@
#pragma once
#include <vcpkg/binaryparagraph.h>
-#include <vcpkg/parse.h>
+#include <vcpkg/paragraphparser.h>
#include <vcpkg/vcpkgpaths.h>
#include <vcpkg/base/expected.h>
@@ -10,13 +10,13 @@ namespace vcpkg::Paragraphs
{
using RawParagraph = Parse::RawParagraph;
- 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<std::vector<RawParagraph>> parse_paragraphs(const std::string& str);
+ ExpectedS<RawParagraph> get_single_paragraph(const Files::Filesystem& fs, const fs::path& control_path);
+ ExpectedS<std::vector<RawParagraph>> get_paragraphs(const Files::Filesystem& fs, const fs::path& control_path);
+ ExpectedS<std::vector<RawParagraph>> parse_paragraphs(const std::string& str, const std::string& origin);
Parse::ParseExpected<SourceControlFile> try_load_port(const Files::Filesystem& fs, const fs::path& control_path);
- Expected<BinaryControlFile> try_load_cached_package(const VcpkgPaths& paths, const PackageSpec& spec);
+ ExpectedS<BinaryControlFile> try_load_cached_package(const VcpkgPaths& paths, const PackageSpec& spec);
struct LoadResults
{
diff --git a/toolsrc/include/vcpkg/parse.h b/toolsrc/include/vcpkg/parse.h
index 4b33e302e..3214305bf 100644
--- a/toolsrc/include/vcpkg/parse.h
+++ b/toolsrc/include/vcpkg/parse.h
@@ -1,38 +1,147 @@
#pragma once
-#include <vcpkg/base/expected.h>
+#include <vcpkg/base/cstringview.h>
#include <vcpkg/base/optional.h>
+#include <vcpkg/base/stringview.h>
+#include <vcpkg/textrowcol.h>
#include <memory>
-#include <unordered_map>
+#include <string>
namespace vcpkg::Parse
{
- struct ParseControlErrorInfo
+ struct IParseError
{
- std::string name;
- std::vector<std::string> missing_fields;
- std::vector<std::string> extra_fields;
- std::error_code error;
+ virtual ~IParseError() = default;
+ virtual std::string format() const = 0;
};
- template<class P>
- using ParseExpected = ExpectedT<std::unique_ptr<P>, std::unique_ptr<ParseControlErrorInfo>>;
+ struct ParseError : IParseError
+ {
+ ParseError(std::string origin, int row, int column, std::string line, std::string message)
+ : origin(std::move(origin)), row(row), column(column), line(std::move(line)), message(std::move(message))
+ {
+ }
+
+ const std::string origin;
+ const int row;
+ const int column;
+ const std::string line;
+ const std::string message;
- using RawParagraph = std::unordered_map<std::string, std::string>;
+ virtual std::string format() const override;
+ };
- struct ParagraphParser
+ struct ParserBase
{
- ParagraphParser(RawParagraph&& fields) : fields(std::move(fields)) {}
+ struct SourceLoc
+ {
+ const char* it;
+ int row;
+ int column;
+ };
+
+ void init(CStringView text, CStringView origin, TextRowCol init_rowcol = {})
+ {
+ m_text = text;
+ m_origin = origin;
+ m_it = text.c_str();
+ row = init_rowcol.row ? init_rowcol.row : 1;
+ column = init_rowcol.column ? init_rowcol.column : 1;
+ }
+
+ static constexpr bool is_whitespace(char ch) { return ch == ' ' || ch == '\t' || ch == '\r' || ch == '\n'; }
+ static constexpr bool is_lower_alpha(char ch) { return ch >= 'a' && ch <= 'z'; }
+ static constexpr bool is_upper_alpha(char ch) { return ch >= 'A' && ch <= 'Z'; }
+ static constexpr bool is_ascii_digit(char ch) { return ch >= '0' && ch <= '9'; }
+ static constexpr bool is_lineend(char ch) { return ch == '\r' || ch == '\n' || ch == '\0'; }
+ static constexpr bool is_alphanum(char ch)
+ {
+ return is_upper_alpha(ch) || is_lower_alpha(ch) || is_ascii_digit(ch);
+ }
+ static constexpr bool is_alphanumdash(char ch) { return is_alphanum(ch) || ch == '-'; }
+
+ StringView skip_whitespace() { return match_zero_or_more(is_whitespace); }
+ StringView skip_tabs_spaces()
+ {
+ return match_zero_or_more([](char ch) { return ch == ' ' || ch == '\t'; });
+ }
+ void skip_to_eof()
+ {
+ while (cur())
+ ++m_it;
+ }
+ void skip_newline()
+ {
+ if (cur() == '\r') next();
+ if (cur() == '\n') next();
+ }
+ void skip_line()
+ {
+ match_until(is_lineend);
+ skip_newline();
+ }
- void required_field(const std::string& fieldname, std::string& out);
- std::string optional_field(const std::string& fieldname) const;
- std::unique_ptr<ParseControlErrorInfo> error_info(const std::string& name) const;
+ template<class Pred>
+ StringView match_zero_or_more(Pred p)
+ {
+ const char* start = m_it;
+ auto ch = cur();
+ while (ch != '\0' && p(ch))
+ ch = next();
+ return {start, m_it};
+ }
+ template<class Pred>
+ StringView match_until(Pred p)
+ {
+ const char* start = m_it;
+ auto ch = cur();
+ while (ch != '\0' && !p(ch))
+ ch = next();
+ return {start, m_it};
+ }
+
+ CStringView text() const { return m_text; }
+ const char* it() const { return m_it; }
+ char cur() const { return *m_it; }
+ SourceLoc cur_loc() const { return {m_it, row, column}; }
+ char next()
+ {
+ char ch = *m_it;
+ // See https://www.gnu.org/prep/standards/standards.html#Errors
+ if (ch == '\t')
+ column = (column + 7) / 8 * 8 + 1; // round to next 8-width tab stop
+ else if (ch == '\n')
+ {
+ row++;
+ column = 1;
+ }
+ else if (ch == '\0')
+ {
+ return '\0';
+ }
+ else
+ {
+ ++column;
+ }
+ return *++m_it;
+ }
+ bool at_eof() const { return *m_it == 0; }
+
+ void add_error(std::string message) { add_error(std::move(message), cur_loc()); }
+ void add_error(std::string message, const SourceLoc& loc);
+
+ const Parse::IParseError* get_error() const { return m_err.get(); }
+ std::unique_ptr<Parse::IParseError> extract_error() { return std::move(m_err); }
private:
- RawParagraph&& fields;
- std::vector<std::string> missing_fields;
- };
+ const char* m_it;
+ int row;
+ int column;
+
+ CStringView m_text;
+ CStringView m_origin;
- std::vector<std::string> parse_comma_list(const std::string& str);
+ std::unique_ptr<IParseError> m_err;
+ };
}
diff --git a/toolsrc/include/vcpkg/portfileprovider.h b/toolsrc/include/vcpkg/portfileprovider.h
index 79f69d9ae..36cdba589 100644
--- a/toolsrc/include/vcpkg/portfileprovider.h
+++ b/toolsrc/include/vcpkg/portfileprovider.h
@@ -1,6 +1,6 @@
#pragma once
-#include <vcpkg/base/optional.h>
+#include <vcpkg/base/expected.h>
#include <vcpkg/base/util.h>
#include <vcpkg/sourceparagraph.h>
#include <vcpkg/vcpkgpaths.h>
@@ -9,14 +9,14 @@ namespace vcpkg::PortFileProvider
{
struct PortFileProvider
{
- virtual Optional<const SourceControlFileLocation&> get_control_file(const std::string& src_name) const = 0;
+ virtual ExpectedS<const SourceControlFileLocation&> get_control_file(const std::string& src_name) const = 0;
virtual std::vector<const SourceControlFileLocation*> load_all_control_files() const = 0;
};
struct MapPortFileProvider : Util::ResourceBase, PortFileProvider
{
explicit MapPortFileProvider(const std::unordered_map<std::string, SourceControlFileLocation>& map);
- Optional<const SourceControlFileLocation&> get_control_file(const std::string& src_name) const override;
+ ExpectedS<const SourceControlFileLocation&> get_control_file(const std::string& src_name) const override;
std::vector<const SourceControlFileLocation*> load_all_control_files() const override;
private:
@@ -27,7 +27,7 @@ namespace vcpkg::PortFileProvider
{
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;
+ ExpectedS<const SourceControlFileLocation&> get_control_file(const std::string& src_name) const override;
std::vector<const SourceControlFileLocation*> load_all_control_files() const override;
private:
diff --git a/toolsrc/include/vcpkg/remove.h b/toolsrc/include/vcpkg/remove.h
index 36aeda2ad..c43bc73c2 100644
--- a/toolsrc/include/vcpkg/remove.h
+++ b/toolsrc/include/vcpkg/remove.h
@@ -21,6 +21,6 @@ namespace vcpkg::Remove
extern const CommandStructure COMMAND_STRUCTURE;
- void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, const Triplet& default_triplet);
+ void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, Triplet default_triplet);
void remove_package(const VcpkgPaths& paths, const PackageSpec& spec, StatusParagraphs* status_db);
}
diff --git a/toolsrc/include/vcpkg/sourceparagraph.h b/toolsrc/include/vcpkg/sourceparagraph.h
index 0574afe74..bdb75fc58 100644
--- a/toolsrc/include/vcpkg/sourceparagraph.h
+++ b/toolsrc/include/vcpkg/sourceparagraph.h
@@ -1,37 +1,20 @@
#pragma once
-#include <vcpkg/packagespec.h>
-#include <vcpkg/parse.h>
-
+#include <string>
#include <vcpkg/base/expected.h>
#include <vcpkg/base/span.h>
#include <vcpkg/base/system.h>
-
#include <vcpkg/base/system.print.h>
-
-#include <string>
+#include <vcpkg/packagespec.h>
+#include <vcpkg/paragraphparser.h>
#include <vector>
namespace vcpkg
{
- struct Dependency
- {
- Features depend;
- std::string qualifier;
-
- std::string name() const;
- static Dependency parse_dependency(std::string name, std::string qualifier);
- };
-
std::vector<FullPackageSpec> filter_dependencies(const std::vector<Dependency>& deps,
- const Triplet& t,
+ Triplet t,
const std::unordered_map<std::string, std::string>& cmake_vars);
- // zlib[uwp] becomes Dependency{"zlib", "uwp"}
- std::vector<Dependency> expand_qualified_dependencies(const std::vector<std::string>& depends);
-
- std::string to_string(const Dependency& dep);
-
struct Type
{
enum
diff --git a/toolsrc/include/vcpkg/statusparagraphs.h b/toolsrc/include/vcpkg/statusparagraphs.h
index fa064de7e..7fcf0e916 100644
--- a/toolsrc/include/vcpkg/statusparagraphs.h
+++ b/toolsrc/include/vcpkg/statusparagraphs.h
@@ -35,10 +35,10 @@ namespace vcpkg
/// <param name="triplet">Triplet</param>
/// <param name="feature">Feature name</param>
/// <returns>Iterator for found spec</returns>
- iterator find(const std::string& name, const Triplet& triplet, const std::string& feature = "");
- const_iterator find(const std::string& name, const Triplet& triplet, const std::string& feature = "") const;
+ iterator find(const std::string& name, Triplet triplet, const std::string& feature = "");
+ const_iterator find(const std::string& name, Triplet triplet, const std::string& feature = "") const;
- std::vector<std::unique_ptr<StatusParagraph>*> find_all(const std::string& name, const Triplet& triplet);
+ std::vector<std::unique_ptr<StatusParagraph>*> find_all(const std::string& name, Triplet triplet);
Optional<InstalledPackageView> find_all_installed(const PackageSpec& spec) const;
diff --git a/toolsrc/include/vcpkg/textrowcol.h b/toolsrc/include/vcpkg/textrowcol.h
new file mode 100644
index 000000000..5bbf6a899
--- /dev/null
+++ b/toolsrc/include/vcpkg/textrowcol.h
@@ -0,0 +1,12 @@
+#pragma once
+
+namespace vcpkg::Parse
+{
+ struct TextRowCol
+ {
+ /// '0' indicates uninitialized; '1' is the first row.
+ int row = 0;
+ /// '0' indicates uninitialized; '1' is the first column.
+ int column = 0;
+ };
+}
diff --git a/toolsrc/include/vcpkg/triplet.h b/toolsrc/include/vcpkg/triplet.h
index f33f40fd5..8d8c3e879 100644
--- a/toolsrc/include/vcpkg/triplet.h
+++ b/toolsrc/include/vcpkg/triplet.h
@@ -27,8 +27,8 @@ namespace vcpkg
void to_string(std::string& out) const;
size_t hash_code() const;
- bool operator==(const Triplet& other) const;
- bool operator<(const Triplet& other) const { return canonical_name() < other.canonical_name(); }
+ bool operator==(Triplet other) const { return this->m_instance == other.m_instance; }
+ bool operator<(Triplet other) const { return canonical_name() < other.canonical_name(); }
private:
static const TripletInstance DEFAULT_INSTANCE;
@@ -38,7 +38,7 @@ namespace vcpkg
const TripletInstance* m_instance;
};
- bool operator!=(const Triplet& left, const Triplet& right);
+ inline bool operator!=(Triplet left, Triplet right) { return !(left == right); }
}
namespace std
@@ -46,6 +46,6 @@ namespace std
template<>
struct hash<vcpkg::Triplet>
{
- size_t operator()(const vcpkg::Triplet& t) const { return t.hash_code(); }
+ size_t operator()(vcpkg::Triplet t) const { return t.hash_code(); }
};
}
diff --git a/toolsrc/include/vcpkg/vcpkgpaths.h b/toolsrc/include/vcpkg/vcpkgpaths.h
index 52d77d283..63d19af2c 100644
--- a/toolsrc/include/vcpkg/vcpkgpaths.h
+++ b/toolsrc/include/vcpkg/vcpkgpaths.h
@@ -52,7 +52,7 @@ namespace vcpkg
std::string name;
fs::path location;
- TripletFile(const std::string& name, const fs::path& location) : name(name), location(location){}
+ TripletFile(const std::string& name, const fs::path& location) : name(name), location(location) {}
};
static Expected<VcpkgPaths> create(const fs::path& vcpkg_root_dir,
@@ -64,10 +64,10 @@ namespace vcpkg
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;
+ bool is_valid_triplet(Triplet t) const;
const std::vector<std::string> get_available_triplets_names() const;
const std::vector<TripletFile>& get_available_triplets() const;
- const fs::path get_triplet_file_path(const Triplet& triplet) const;
+ const fs::path get_triplet_file_path(Triplet triplet) const;
fs::path root;
fs::path packages;