diff options
| author | Robert Schumacher <roschuma@microsoft.com> | 2017-06-17 02:39:14 -0700 |
|---|---|---|
| committer | Robert Schumacher <roschuma@microsoft.com> | 2017-06-20 09:36:21 -0700 |
| commit | 8741214bf69d1209a1e6d405ed8561d27f04436a (patch) | |
| tree | 85325eb4b2d2c1c15eb8bd58426dac5462242d4e | |
| parent | 8c4d55b8f304c74aeb95878cfe354830ff4abc88 (diff) | |
| download | vcpkg-8741214bf69d1209a1e6d405ed8561d27f04436a.tar.gz vcpkg-8741214bf69d1209a1e6d405ed8561d27f04436a.zip | |
[vcpkg] Use unique_ptr<> for paragraphs. Post-parser phase rework.
28 files changed, 387 insertions, 376 deletions
diff --git a/toolsrc/include/Paragraphs.h b/toolsrc/include/Paragraphs.h index 83a32b2af..60f509266 100644 --- a/toolsrc/include/Paragraphs.h +++ b/toolsrc/include/Paragraphs.h @@ -1,36 +1,38 @@ #pragma once +#include <map> + #include "BinaryParagraph.h" #include "VcpkgPaths.h" #include "VersionT.h" #include "filesystem_fs.h" +#include "vcpkg_Parse.h" #include "vcpkg_expected.h" -#include <map> namespace vcpkg::Paragraphs { - using ParagraphDataMap = std::unordered_map<std::string, std::string>; + using RawParagraph = Parse::RawParagraph; - Expected<ParagraphDataMap> get_single_paragraph(const Files::Filesystem& fs, const fs::path& control_path); - Expected<std::vector<ParagraphDataMap>> get_paragraphs(const Files::Filesystem& fs, const fs::path& control_path); - Expected<ParagraphDataMap> parse_single_paragraph(const std::string& str); - Expected<std::vector<ParagraphDataMap>> parse_paragraphs(const std::string& str); + 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); - ExpectedT<SourceControlFile, ParseControlErrorInfo> try_load_port(const Files::Filesystem& fs, - const fs::path& control_path); + Parse::ParseExpected<SourceControlFile> try_load_port(const Files::Filesystem& fs, const fs::path& control_path); Expected<BinaryParagraph> try_load_cached_package(const VcpkgPaths& paths, const PackageSpec& spec); struct LoadResults { - std::vector<SourceControlFile> paragraphs; - std::vector<ParseControlErrorInfo> errors; + std::vector<std::unique_ptr<SourceControlFile>> paragraphs; + std::vector<std::unique_ptr<Parse::ParseControlErrorInfo>> errors; }; LoadResults try_load_all_ports(const Files::Filesystem& fs, const fs::path& ports_dir); - std::vector<SourceControlFile> load_all_ports(const Files::Filesystem& fs, const fs::path& ports_dir); + std::vector<std::unique_ptr<SourceControlFile>> load_all_ports(const Files::Filesystem& fs, + const fs::path& ports_dir); - std::map<std::string, VersionT> extract_port_names_and_versions( - const std::vector<SourceParagraph>& source_paragraphs); + std::map<std::string, VersionT> load_all_port_names_and_versions(const Files::Filesystem& fs, + const fs::path& ports_dir); } diff --git a/toolsrc/include/SourceParagraph.h b/toolsrc/include/SourceParagraph.h index 31c9560cc..e85884b51 100644 --- a/toolsrc/include/SourceParagraph.h +++ b/toolsrc/include/SourceParagraph.h @@ -1,6 +1,7 @@ #pragma once #include "Span.h" +#include "vcpkg_Parse.h" #include "vcpkg_System.h" #include "vcpkg_expected.h" @@ -22,13 +23,6 @@ namespace vcpkg const std::string& to_string(const Dependency& dep); - struct ParseControlErrorInfo - { - std::string name; - std::string remaining_fields_as_string; - std::error_code error; - }; - struct FeatureParagraph { std::string name; @@ -47,23 +41,19 @@ namespace vcpkg std::string maintainer; std::vector<std::string> supports; std::vector<Dependency> depends; - std::string default_features; + std::vector<std::string> default_features; }; struct SourceControlFile { - static ExpectedT<SourceControlFile, ParseControlErrorInfo> parse_control_file( - std::vector<std::unordered_map<std::string, std::string>>&& control_paragraphs); + static Parse::ParseExpected<SourceControlFile> parse_control_file( + std::vector<Parse::RawParagraph>&& control_paragraphs); - SourceParagraph core_paragraph; + std::unique_ptr<SourceParagraph> core_paragraph; std::vector<std::unique_ptr<FeatureParagraph>> feature_paragraphs; - - std::vector<ParseControlErrorInfo> errors; }; - std::vector<SourceParagraph> getSourceParagraphs(const std::vector<SourceControlFile>& control_files); - - void print_error_message(span<const ParseControlErrorInfo> error_info_list); - inline void print_error_message(const ParseControlErrorInfo& error_info_list) + void print_error_message(span<const std::unique_ptr<Parse::ParseControlErrorInfo>> error_info_list); + inline void print_error_message(const std::unique_ptr<Parse::ParseControlErrorInfo>& error_info_list) { return print_error_message({&error_info_list, 1}); } diff --git a/toolsrc/include/StatusParagraph.h b/toolsrc/include/StatusParagraph.h index 2d1815dc0..b56533d65 100644 --- a/toolsrc/include/StatusParagraph.h +++ b/toolsrc/include/StatusParagraph.h @@ -29,7 +29,7 @@ namespace vcpkg struct StatusParagraph { StatusParagraph(); - explicit StatusParagraph(const std::unordered_map<std::string, std::string>& fields); + explicit StatusParagraph(std::unordered_map<std::string, std::string>&& fields); BinaryParagraph package; Want want; diff --git a/toolsrc/include/vcpkg_Build.h b/toolsrc/include/vcpkg_Build.h index e13f66029..9a4e2baeb 100644 --- a/toolsrc/include/vcpkg_Build.h +++ b/toolsrc/include/vcpkg_Build.h @@ -120,14 +120,20 @@ namespace vcpkg::Build COUNT, }; - Optional<BuildPolicy> to_build_policy(const std::string& str); + constexpr std::array<BuildPolicy, size_t(BuildPolicy::COUNT)> g_all_policies = { + BuildPolicy::EMPTY_PACKAGE, + BuildPolicy::DLLS_WITHOUT_LIBS, + BuildPolicy::ONLY_RELEASE_CRT, + BuildPolicy::EMPTY_INCLUDE_FOLDER, + BuildPolicy::ALLOW_OBSOLETE_MSVCRT, + }; const std::string& to_string(BuildPolicy policy); CStringView to_cmake_variable(BuildPolicy policy); struct BuildPolicies { - BuildPolicies() {} + BuildPolicies() = default; BuildPolicies(std::map<BuildPolicy, bool>&& map) : m_policies(std::move(map)) {} inline bool is_enabled(BuildPolicy policy) const diff --git a/toolsrc/include/vcpkg_Parse.h b/toolsrc/include/vcpkg_Parse.h new file mode 100644 index 000000000..a2eb152dc --- /dev/null +++ b/toolsrc/include/vcpkg_Parse.h @@ -0,0 +1,36 @@ +#pragma once + +#include <memory> +#include <unordered_map> + +#include "vcpkg_expected.h" +#include "vcpkg_optional.h" + +namespace vcpkg::Parse +{ + struct ParseControlErrorInfo + { + std::string name; + std::vector<std::string> missing_fields; + std::vector<std::string> extra_fields; + std::error_code error; + }; + + template<class P> + using ParseExpected = 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); + std::unique_ptr<ParseControlErrorInfo> error_info(const std::string& name) const; + + private: + RawParagraph&& fields; + std::vector<std::string> missing_fields; + }; +} diff --git a/toolsrc/include/vcpkg_expected.h b/toolsrc/include/vcpkg_expected.h index 15dbf5e79..9637ec087 100644 --- a/toolsrc/include/vcpkg_expected.h +++ b/toolsrc/include/vcpkg_expected.h @@ -9,8 +9,10 @@ namespace vcpkg struct ErrorHolder { ErrorHolder() : m_is_error(false) {} - ErrorHolder(const Err& err) : m_is_error(true), m_err(err) {} - ErrorHolder(Err&& err) : m_is_error(true), m_err(std::move(err)) {} + template<class U> + ErrorHolder(U&& err) : m_is_error(true), m_err(std::forward<U>(err)) + { + } constexpr bool has_error() const { return m_is_error; } diff --git a/toolsrc/include/vcpkglib.h b/toolsrc/include/vcpkglib.h index df64e5463..bd2400b77 100644 --- a/toolsrc/include/vcpkglib.h +++ b/toolsrc/include/vcpkglib.h @@ -36,4 +36,5 @@ namespace vcpkg const fs::path& cmake_script, const std::vector<CMakeVariable>& pass_variables); + std::string shorten_description(const std::string& desc); } // namespace vcpkg diff --git a/toolsrc/include/vcpkglib_helpers.h b/toolsrc/include/vcpkglib_helpers.h deleted file mode 100644 index a8ddcde4d..000000000 --- a/toolsrc/include/vcpkglib_helpers.h +++ /dev/null @@ -1,18 +0,0 @@ -#pragma once - -#include <unordered_map> - -namespace vcpkg::details -{ - std::string optional_field(const std::unordered_map<std::string, std::string>& fields, - const std::string& fieldname); - std::string remove_optional_field(std::unordered_map<std::string, std::string>* fields, - const std::string& fieldname); - - std::string required_field(const std::unordered_map<std::string, std::string>& fields, - const std::string& fieldname); - std::string remove_required_field(std::unordered_map<std::string, std::string>* fields, - const std::string& fieldname); - - std::string shorten_description(const std::string& desc); -} diff --git a/toolsrc/src/BinaryParagraph.cpp b/toolsrc/src/BinaryParagraph.cpp index 21980cd7d..af76c6b29 100644 --- a/toolsrc/src/BinaryParagraph.cpp +++ b/toolsrc/src/BinaryParagraph.cpp @@ -2,13 +2,11 @@ #include "BinaryParagraph.h" #include "vcpkg_Checks.h" -#include "vcpkglib_helpers.h" - -using namespace vcpkg::details; +#include "vcpkg_Parse.h" namespace vcpkg { - namespace BinaryParagraphRequiredField + namespace Fields { static const std::string PACKAGE = "Package"; static const std::string VERSION = "Version"; @@ -16,7 +14,7 @@ namespace vcpkg static const std::string MULTI_ARCH = "Multi-Arch"; } - namespace BinaryParagraphOptionalField + namespace Fields { static const std::string DESCRIPTION = "Description"; static const std::string MAINTAINER = "Maintainer"; @@ -27,22 +25,36 @@ namespace vcpkg BinaryParagraph::BinaryParagraph(std::unordered_map<std::string, std::string> fields) { - const std::string name = details::remove_required_field(&fields, BinaryParagraphRequiredField::PACKAGE); - const std::string architecture = - details::remove_required_field(&fields, BinaryParagraphRequiredField::ARCHITECTURE); - const Triplet triplet = Triplet::from_canonical_name(architecture); + using namespace vcpkg::Parse; - this->spec = PackageSpec::from_name_and_triplet(name, triplet).value_or_exit(VCPKG_LINE_INFO); - this->version = details::remove_required_field(&fields, BinaryParagraphRequiredField::VERSION); + ParagraphParser parser(std::move(fields)); - this->description = details::remove_optional_field(&fields, BinaryParagraphOptionalField::DESCRIPTION); - this->maintainer = details::remove_optional_field(&fields, BinaryParagraphOptionalField::MAINTAINER); + { + std::string name; + 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)) + .value_or_exit(VCPKG_LINE_INFO); + } - std::string multi_arch = details::remove_required_field(&fields, BinaryParagraphRequiredField::MULTI_ARCH); - Checks::check_exit(VCPKG_LINE_INFO, multi_arch == "same", "Multi-Arch must be 'same' but was %s", multi_arch); + parser.required_field(Fields::VERSION, this->version); + this->description = parser.optional_field(Fields::DESCRIPTION); + this->maintainer = parser.optional_field(Fields::MAINTAINER); + + std::string multi_arch; + parser.required_field(Fields::MULTI_ARCH, multi_arch); - std::string deps = details::remove_optional_field(&fields, BinaryParagraphOptionalField::DEPENDS); - this->depends = parse_comma_list(deps); + this->depends = parse_comma_list(parser.optional_field(Fields::DEPENDS)); + + if (auto err = parser.error_info(this->spec.name())) + { + print_error_message(err); + Checks::exit_fail(VCPKG_LINE_INFO); + } + + // prefer failing above when possible because it gives better information + Checks::check_exit(VCPKG_LINE_INFO, multi_arch == "same", "Multi-Arch must be 'same' but was %s", multi_arch); } BinaryParagraph::BinaryParagraph(const SourceParagraph& spgh, const Triplet& triplet) diff --git a/toolsrc/src/Paragraphs.cpp b/toolsrc/src/Paragraphs.cpp index 440d04ce4..3749e919e 100644 --- a/toolsrc/src/Paragraphs.cpp +++ b/toolsrc/src/Paragraphs.cpp @@ -4,6 +4,8 @@ #include "Paragraphs.h" #include "vcpkg_Files.h" +using namespace vcpkg::Parse; + namespace vcpkg::Paragraphs { struct Parser @@ -201,9 +203,8 @@ namespace vcpkg::Paragraphs return Parser(str.c_str(), str.c_str() + str.size()).get_paragraphs(); } - ExpectedT<SourceControlFile, ParseControlErrorInfo> try_load_port(const Files::Filesystem& fs, const fs::path& path) + ParseExpected<SourceControlFile> try_load_port(const Files::Filesystem& fs, const fs::path& path) { - ParseControlErrorInfo error_info; Expected<std::vector<std::unordered_map<std::string, std::string>>> pghs = get_paragraphs(fs, path / "CONTROL"); if (auto vector_pghs = pghs.get()) { @@ -212,14 +213,16 @@ namespace vcpkg::Paragraphs { if (auto ptr = csf.get()) { - ptr->core_paragraph.default_features.clear(); - ptr->feature_paragraphs.clear(); + Checks::check_exit(VCPKG_LINE_INFO, ptr->get() != nullptr); + ptr->get()->core_paragraph->default_features.clear(); + ptr->get()->feature_paragraphs.clear(); } } return csf; } - error_info.name = path.filename().generic_u8string(); - error_info.error = pghs.error(); + auto error_info = std::make_unique<ParseControlErrorInfo>(); + error_info->name = path.filename().generic_u8string(); + error_info->error = pghs.error(); return error_info; } @@ -241,20 +244,21 @@ namespace vcpkg::Paragraphs LoadResults ret; for (auto&& path : fs.get_files_non_recursive(ports_dir)) { - ExpectedT<SourceControlFile, ParseControlErrorInfo> source_paragraph = try_load_port(fs, path); - if (auto srcpgh = source_paragraph.get()) + auto maybe_spgh = try_load_port(fs, path); + if (auto spgh = maybe_spgh.get()) { - ret.paragraphs.emplace_back(std::move(*srcpgh)); + ret.paragraphs.emplace_back(std::move(*spgh)); } else { - ret.errors.emplace_back(source_paragraph.error()); + ret.errors.emplace_back(std::move(maybe_spgh).error()); } } return ret; } - std::vector<SourceControlFile> load_all_ports(const Files::Filesystem& fs, const fs::path& ports_dir) + std::vector<std::unique_ptr<SourceControlFile>> load_all_ports(const Files::Filesystem& fs, + const fs::path& ports_dir) { auto results = try_load_all_ports(fs, ports_dir); if (!results.errors.empty()) @@ -265,14 +269,14 @@ namespace vcpkg::Paragraphs return std::move(results.paragraphs); } - std::map<std::string, VersionT> extract_port_names_and_versions( - const std::vector<SourceParagraph>& source_paragraphs) + std::map<std::string, VersionT> load_all_port_names_and_versions(const Files::Filesystem& fs, + const fs::path& ports_dir) { + auto all_ports = load_all_ports(fs, ports_dir); + std::map<std::string, VersionT> names_and_versions; - for (const SourceParagraph& port : source_paragraphs) - { - names_and_versions.emplace(port.name, port.version); - } + for (auto&& port : all_ports) + names_and_versions.emplace(port->core_paragraph->name, port->core_paragraph->version); return names_and_versions; } diff --git a/toolsrc/src/SourceParagraph.cpp b/toolsrc/src/SourceParagraph.cpp index a938feb99..83b8e2e2d 100644 --- a/toolsrc/src/SourceParagraph.cpp +++ b/toolsrc/src/SourceParagraph.cpp @@ -8,73 +8,56 @@ #include "vcpkg_Util.h" #include "vcpkg_expected.h" -#include "vcpkglib_helpers.h" - namespace vcpkg { - bool g_feature_packages = false; - namespace SourceParagraphRequiredField - { - static const std::string SOURCE = "Source"; - static const std::string VERSION = "Version"; - } + using namespace vcpkg::Parse; - namespace SourceParagraphOptionalField + bool g_feature_packages = false; + namespace Fields { + static const std::string BUILD_DEPENDS = "Build-Depends"; + static const std::string DEFAULTFEATURES = "Default-Features"; static const std::string DESCRIPTION = "Description"; + static const std::string FEATURE = "Feature"; static const std::string MAINTAINER = "Maintainer"; - static const std::string BUILD_DEPENDS = "Build-Depends"; + static const std::string SOURCE = "Source"; static const std::string SUPPORTS = "Supports"; - static const std::string DEFAULTFEATURES = "Default-Features"; + static const std::string VERSION = "Version"; } static span<const std::string> get_list_of_valid_fields() { - static const std::string valid_fields[] = {SourceParagraphRequiredField::SOURCE, - SourceParagraphRequiredField::VERSION, - - SourceParagraphOptionalField::DESCRIPTION, - SourceParagraphOptionalField::MAINTAINER, - SourceParagraphOptionalField::BUILD_DEPENDS, - SourceParagraphOptionalField::SUPPORTS}; + static const std::string valid_fields[] = { + Fields::SOURCE, Fields::VERSION, Fields::DESCRIPTION, Fields::MAINTAINER, Fields::BUILD_DEPENDS, + }; return valid_fields; } - namespace FeatureParagraphRequiredField - { - static const std::string FEATURE = "Feature"; - } - - namespace FeatureParagraphOptionalField - { - static const std::string DESCRIPTION = "Description"; - static const std::string BUILD_DEPENDS = "Build-Depends"; - } - - void print_error_message(span<const ParseControlErrorInfo> error_info_list) + void print_error_message(span<const std::unique_ptr<Parse::ParseControlErrorInfo>> error_info_list) { Checks::check_exit(VCPKG_LINE_INFO, error_info_list.size() > 0); for (auto&& error_info : error_info_list) { - if (error_info.error) + 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::Color::error, "Error: while loading %s: %s", error_info->name, error_info->error.message()); } } bool have_remaining_fields = false; for (auto&& error_info : error_info_list) { - if (!error_info.remaining_fields_as_string.empty()) + if (!error_info->extra_fields.empty()) { System::println(System::Color::error, "Error: There are invalid fields in the Source Paragraph of %s", - error_info.name); + error_info->name); System::println("The following fields were not expected:\n\n %s\n\n", - error_info.remaining_fields_as_string); + Strings::join("\n ", error_info->extra_fields)); have_remaining_fields = true; } } @@ -86,71 +69,75 @@ namespace vcpkg System::println("Different source may be available for vcpkg. Use .\\bootstrap-vcpkg.bat to update.\n"); } } - std::vector<SourceParagraph> getSourceParagraphs(const std::vector<SourceControlFile>& control_files) + + static ParseExpected<SourceParagraph> parse_source_paragraph(RawParagraph&& fields) { - return Util::fmap(control_files, [](const SourceControlFile& x) { return x.core_paragraph; }); + ParagraphParser parser(std::move(fields)); + + auto spgh = std::make_unique<SourceParagraph>(); + + parser.required_field(Fields::SOURCE, spgh->name); + parser.required_field(Fields::VERSION, spgh->version); + + spgh->description = parser.optional_field(Fields::DESCRIPTION); + spgh->maintainer = parser.optional_field(Fields::MAINTAINER); + spgh->depends = expand_qualified_dependencies(parse_comma_list(parser.optional_field(Fields::BUILD_DEPENDS))); + spgh->supports = parse_comma_list(parser.optional_field(Fields::SUPPORTS)); + spgh->default_features = parse_comma_list(parser.optional_field(Fields::DEFAULTFEATURES)); + + auto err = parser.error_info(spgh->name); + if (err) + return std::move(err); + else + return std::move(spgh); } - ExpectedT<SourceControlFile, ParseControlErrorInfo> SourceControlFile::parse_control_file( - std::vector<std::unordered_map<std::string, std::string>>&& control_paragraphs) + static ParseExpected<FeatureParagraph> parse_feature_paragraph(RawParagraph&& fields) { - if (control_paragraphs.size() == 0) - { - return ExpectedT<SourceControlFile, ParseControlErrorInfo>(); - } - auto&& fields = control_paragraphs.front(); + ParagraphParser parser(std::move(fields)); - SourceControlFile control_file; - SourceParagraph& sparagraph = control_file.core_paragraph; - sparagraph.name = details::remove_required_field(&fields, SourceParagraphRequiredField::SOURCE); - sparagraph.version = details::remove_required_field(&fields, SourceParagraphRequiredField::VERSION); - sparagraph.description = details::remove_optional_field(&fields, SourceParagraphOptionalField::DESCRIPTION); - sparagraph.maintainer = details::remove_optional_field(&fields, SourceParagraphOptionalField::MAINTAINER); + auto fpgh = std::make_unique<FeatureParagraph>(); - std::string deps = details::remove_optional_field(&fields, SourceParagraphOptionalField::BUILD_DEPENDS); - sparagraph.depends = expand_qualified_dependencies(parse_comma_list(deps)); + parser.required_field(Fields::FEATURE, fpgh->name); + parser.required_field(Fields::DESCRIPTION, fpgh->description); - std::string sups = details::remove_optional_field(&fields, SourceParagraphOptionalField::SUPPORTS); - sparagraph.supports = parse_comma_list(sups); + fpgh->depends = expand_qualified_dependencies(parse_comma_list(parser.optional_field(Fields::BUILD_DEPENDS))); - sparagraph.default_features = - details::remove_optional_field(&fields, SourceParagraphOptionalField::DEFAULTFEATURES); + auto err = parser.error_info(fpgh->name); + if (err) + return std::move(err); + else + return std::move(fpgh); + } - if (!fields.empty()) + ParseExpected<SourceControlFile> SourceControlFile::parse_control_file( + std::vector<std::unordered_map<std::string, std::string>>&& control_paragraphs) + { + if (control_paragraphs.size() == 0) { - const std::vector<std::string> remaining_fields = Maps::extract_keys(fields); + return std::make_unique<Parse::ParseControlErrorInfo>(); + } - const std::string remaining_fields_as_string = Strings::join("\n ", remaining_fields); + auto control_file = std::make_unique<SourceControlFile>(); - return ParseControlErrorInfo{sparagraph.name, remaining_fields_as_string}; - } + auto maybe_source = parse_source_paragraph(std::move(control_paragraphs.front())); + if (auto source = maybe_source.get()) + control_file->core_paragraph = std::move(*source); + else + return std::move(maybe_source).error(); control_paragraphs.erase(control_paragraphs.begin()); for (auto&& feature_pgh : control_paragraphs) { - control_file.feature_paragraphs.emplace_back(std::make_unique<FeatureParagraph>()); - - FeatureParagraph& fparagraph = *control_file.feature_paragraphs.back(); - - fparagraph.name = details::remove_required_field(&feature_pgh, FeatureParagraphRequiredField::FEATURE); - fparagraph.description = - details::remove_required_field(&feature_pgh, FeatureParagraphOptionalField::DESCRIPTION); - std::string feature_deps = - details::remove_optional_field(&feature_pgh, FeatureParagraphOptionalField::BUILD_DEPENDS); - fparagraph.depends = expand_qualified_dependencies(parse_comma_list(feature_deps)); - - if (!feature_pgh.empty()) - { - const std::vector<std::string> remaining_fields = Maps::extract_keys(feature_pgh); - - const std::string remaining_fields_as_string = Strings::join("\n ", remaining_fields); - - return ParseControlErrorInfo{sparagraph.name, remaining_fields_as_string}; - } + auto maybe_feature = parse_feature_paragraph(std::move(feature_pgh)); + if (auto feature = maybe_feature.get()) + control_file->feature_paragraphs.emplace_back(std::move(*feature)); + else + return std::move(maybe_feature).error(); } - return control_file; + return std::move(control_file); } std::vector<Dependency> vcpkg::expand_qualified_dependencies(const std::vector<std::string>& depends) diff --git a/toolsrc/src/StatusParagraph.cpp b/toolsrc/src/StatusParagraph.cpp index b9ceed278..5b5c3978f 100644 --- a/toolsrc/src/StatusParagraph.cpp +++ b/toolsrc/src/StatusParagraph.cpp @@ -1,9 +1,8 @@ #include "pch.h" #include "StatusParagraph.h" -#include "vcpkglib_helpers.h" -using namespace vcpkg::details; +using namespace vcpkg::Parse; namespace vcpkg { @@ -24,9 +23,14 @@ namespace vcpkg .push_back('\n'); } - StatusParagraph::StatusParagraph(const std::unordered_map<std::string, std::string>& fields) : package(fields) + StatusParagraph::StatusParagraph(std::unordered_map<std::string, std::string>&& fields) { - std::string status_field = required_field(fields, BinaryParagraphRequiredField::STATUS); + auto status_it = fields.find(BinaryParagraphRequiredField::STATUS); + Checks::check_exit(VCPKG_LINE_INFO, status_it != fields.end(), "Expected 'Status' field in status paragraph"); + std::string status_field = std::move(status_it->second); + fields.erase(status_it); + + this->package = BinaryParagraph(std::move(fields)); auto b = status_field.begin(); auto mark = b; diff --git a/toolsrc/src/commands_build.cpp b/toolsrc/src/commands_build.cpp index a9e4f574e..4da9cede2 100644 --- a/toolsrc/src/commands_build.cpp +++ b/toolsrc/src/commands_build.cpp @@ -11,6 +11,8 @@ #include "vcpkglib.h" using vcpkg::Build::BuildResult; +using vcpkg::Parse::ParseControlErrorInfo; +using vcpkg::Parse::ParseExpected; namespace vcpkg::Commands::BuildCommand { @@ -34,7 +36,7 @@ namespace vcpkg::Commands::BuildCommand Checks::exit_success(VCPKG_LINE_INFO); } - const ExpectedT<SourceControlFile, ParseControlErrorInfo> source_control_file = + const ParseExpected<SourceControlFile> source_control_file = Paragraphs::try_load_port(paths.get_filesystem(), port_dir); if (!source_control_file.has_value()) @@ -47,18 +49,18 @@ namespace vcpkg::Commands::BuildCommand { System::println("%s \n", str); } - const SourceControlFile& scf = source_control_file.value_or_exit(VCPKG_LINE_INFO); + const auto& scf = source_control_file.value_or_exit(VCPKG_LINE_INFO); Checks::check_exit(VCPKG_LINE_INFO, - spec.name() == scf.core_paragraph.name, + spec.name() == scf->core_paragraph->name, "The Name: field inside the CONTROL does not match the port directory: '%s' != '%s'", - scf.core_paragraph.name, + scf->core_paragraph->name, spec.name()); StatusParagraphs status_db = database_load_check(paths); Build::BuildPackageOptions build_package_options{Build::UseHeadVersion::NO, Build::AllowDownloads::YES}; const Build::BuildPackageConfig build_config{ - scf.core_paragraph, spec.triplet(), paths.port_dir(spec), build_package_options}; + *scf->core_paragraph, spec.triplet(), paths.port_dir(spec), build_package_options}; const auto result = Build::build_package(paths, build_config, status_db); if (result.code == BuildResult::CASCADED_DUE_TO_MISSING_DEPENDENCIES) diff --git a/toolsrc/src/commands_ci.cpp b/toolsrc/src/commands_ci.cpp index 65e44e847..7ffc7577a 100644 --- a/toolsrc/src/commands_ci.cpp +++ b/toolsrc/src/commands_ci.cpp @@ -8,6 +8,7 @@ #include "vcpkg_Files.h" #include "vcpkg_Input.h" #include "vcpkg_System.h" +#include "vcpkg_Util.h" #include "vcpkglib.h" namespace vcpkg::Commands::CI @@ -21,14 +22,10 @@ namespace vcpkg::Commands::CI const Triplet& triplet) { auto ports = Paragraphs::load_all_ports(fs, ports_directory); - std::vector<PackageSpec> specs; - for (const SourceControlFile& control_file : ports) - { - const SourceParagraph& p = control_file.core_paragraph; - specs.push_back(PackageSpec::from_name_and_triplet(p.name, triplet).value_or_exit(VCPKG_LINE_INFO)); - } - - return specs; + return Util::fmap(ports, [&](auto&& control_file) -> PackageSpec { + return PackageSpec::from_name_and_triplet(control_file->core_paragraph->name, triplet) + .value_or_exit(VCPKG_LINE_INFO); + }); } void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, const Triplet& default_triplet) diff --git a/toolsrc/src/commands_depends.cpp b/toolsrc/src/commands_depends.cpp index 468bf5d72..ccfe58e4e 100644 --- a/toolsrc/src/commands_depends.cpp +++ b/toolsrc/src/commands_depends.cpp @@ -15,9 +15,9 @@ namespace vcpkg::Commands::DependInfo const auto source_control_files = Paragraphs::load_all_ports(paths.get_filesystem(), paths.ports); - for (const SourceControlFile& source_control_file : source_control_files) + for (auto&& source_control_file : source_control_files) { - const SourceParagraph& source_paragraph = source_control_file.core_paragraph; + const SourceParagraph& source_paragraph = *source_control_file->core_paragraph; auto s = Strings::join(", ", source_paragraph.depends, [](const Dependency& d) { return d.name; }); System::println("%s: %s", source_paragraph.name, s); } diff --git a/toolsrc/src/commands_list.cpp b/toolsrc/src/commands_list.cpp index d21883fc2..9bc9bcc08 100644 --- a/toolsrc/src/commands_list.cpp +++ b/toolsrc/src/commands_list.cpp @@ -3,7 +3,6 @@ #include "vcpkg_Commands.h" #include "vcpkg_System.h" #include "vcpkglib.h" -#include "vcpkglib_helpers.h" namespace vcpkg::Commands::List { @@ -20,7 +19,7 @@ namespace vcpkg::Commands::List System::println("%-27s %-16s %s", pgh.package.displayname(), pgh.package.version, - details::shorten_description(pgh.package.description)); + vcpkg::shorten_description(pgh.package.description)); } } diff --git a/toolsrc/src/commands_portsdiff.cpp b/toolsrc/src/commands_portsdiff.cpp index e872c394d..83d62896f 100644 --- a/toolsrc/src/commands_portsdiff.cpp +++ b/toolsrc/src/commands_portsdiff.cpp @@ -97,10 +97,8 @@ namespace vcpkg::Commands::PortsDiff L".vcpkg-root", git_exe.native()); System::cmd_execute_clean(cmd); - const std::vector<SourceControlFile> source_control_files = - Paragraphs::load_all_ports(paths.get_filesystem(), temp_checkout_path / ports_dir_name_as_string); - const std::map<std::string, VersionT> names_and_versions = - Paragraphs::extract_port_names_and_versions(getSourceParagraphs(source_control_files)); + const std::map<std::string, VersionT> names_and_versions = Paragraphs::load_all_port_names_and_versions( + paths.get_filesystem(), temp_checkout_path / ports_dir_name_as_string); fs.remove_all(temp_checkout_path, ec); return names_and_versions; } diff --git a/toolsrc/src/commands_search.cpp b/toolsrc/src/commands_search.cpp index b39d21887..fee99a5db 100644 --- a/toolsrc/src/commands_search.cpp +++ b/toolsrc/src/commands_search.cpp @@ -5,7 +5,6 @@ #include "vcpkg_Commands.h" #include "vcpkg_System.h" #include "vcpkglib.h" -#include "vcpkglib_helpers.h" namespace vcpkg::Commands::Search { @@ -19,16 +18,17 @@ namespace vcpkg::Commands::Search return output; } - static std::string create_graph_as_string(const std::vector<SourceControlFile>& source_control_files) + static std::string create_graph_as_string( + const std::vector<std::unique_ptr<SourceControlFile>>& source_control_files) { int empty_node_count = 0; std::string s; s.append("digraph G{ rankdir=LR; edge [minlen=3]; overlap=false;"); - for (const SourceControlFile& source_control_file : source_control_files) + for (const auto& source_control_file : source_control_files) { - const SourceParagraph& source_paragraph = source_control_file.core_paragraph; + const SourceParagraph& source_paragraph = *source_control_file->core_paragraph; if (source_paragraph.depends.empty()) { empty_node_count++; @@ -59,7 +59,7 @@ namespace vcpkg::Commands::Search System::println("%-20s %-16s %s", source_paragraph.name, source_paragraph.version, - details::shorten_description(source_paragraph.description)); + vcpkg::shorten_description(source_paragraph.description)); } } @@ -73,7 +73,7 @@ namespace vcpkg::Commands::Search { System::println("%-37s %s", name + "[" + feature_paragraph.name + "]", - details::shorten_description(feature_paragraph.description)); + vcpkg::shorten_description(feature_paragraph.description)); } } @@ -99,7 +99,7 @@ namespace vcpkg::Commands::Search for (auto&& error : sources_and_errors.errors) { System::println( - System::Color::warning, "Warning: an error occurred while parsing '%s'", error.name); + System::Color::warning, "Warning: an error occurred while parsing '%s'", error->name); } System::println(System::Color::warning, "Use '--debug' to get more information about the parse failures.\n"); @@ -116,12 +116,12 @@ namespace vcpkg::Commands::Search if (args.command_arguments.empty()) { - for (const SourceControlFile& source_control_file : source_paragraphs) + for (const auto& source_control_file : source_paragraphs) { - do_print(source_control_file.core_paragraph, options.find(OPTION_FULLDESC) != options.cend()); - for (auto&& feature_paragraph : source_control_file.feature_paragraphs) + do_print(*source_control_file->core_paragraph, options.find(OPTION_FULLDESC) != options.cend()); + for (auto&& feature_paragraph : source_control_file->feature_paragraphs) { - do_print(source_control_file.core_paragraph.name, + do_print(source_control_file->core_paragraph->name, *feature_paragraph, options.find(OPTION_FULLDESC) != options.cend()); } @@ -133,9 +133,9 @@ namespace vcpkg::Commands::Search // At this point there is 1 argument auto&& args_zero = args.command_arguments[0]; - for (const SourceControlFile& source_control_file : source_paragraphs) + for (const auto& source_control_file : source_paragraphs) { - auto&& sp = source_control_file.core_paragraph; + auto&& sp = *source_control_file->core_paragraph; bool contains_name = icontains(sp.name, args_zero); if (contains_name || icontains(sp.description, args_zero)) @@ -143,7 +143,7 @@ namespace vcpkg::Commands::Search do_print(sp, options.find(OPTION_FULLDESC) != options.cend()); } - for (auto&& feature_paragraph : source_control_file.feature_paragraphs) + for (auto&& feature_paragraph : source_control_file->feature_paragraphs) { if (contains_name || icontains(feature_paragraph->name, args_zero) || icontains(feature_paragraph->description, args_zero)) diff --git a/toolsrc/src/commands_update.cpp b/toolsrc/src/commands_update.cpp index f00a89da4..35f24af12 100644 --- a/toolsrc/src/commands_update.cpp +++ b/toolsrc/src/commands_update.cpp @@ -15,10 +15,8 @@ namespace vcpkg::Commands::Update std::vector<OutdatedPackage> find_outdated_packages(const VcpkgPaths& paths, const StatusParagraphs& status_db) { - auto source_control_files = Paragraphs::load_all_ports(paths.get_filesystem(), paths.ports); - const std::vector<SourceParagraph> source_paragraphs = getSourceParagraphs(source_control_files); const std::map<std::string, VersionT> src_names_to_versions = - Paragraphs::extract_port_names_and_versions(source_paragraphs); + Paragraphs::load_all_port_names_and_versions(paths.get_filesystem(), paths.ports); const std::vector<StatusParagraph*> installed_packages = get_installed_ports(status_db); std::vector<OutdatedPackage> output; @@ -67,7 +65,8 @@ namespace vcpkg::Commands::Update System::println("\n" "To update these packages, run\n" " .\\vcpkg remove --outdated\n" - " .\\vcpkg install " + install_line); + " .\\vcpkg install " + + install_line); } auto version_file = paths.get_filesystem().read_contents(paths.root / "toolsrc" / "VERSION.txt"); diff --git a/toolsrc/src/tests_paragraph.cpp b/toolsrc/src/tests_paragraph.cpp index 8dff520fb..2a53cc8b4 100644 --- a/toolsrc/src/tests_paragraph.cpp +++ b/toolsrc/src/tests_paragraph.cpp @@ -33,11 +33,11 @@ namespace UnitTest1 Assert::IsTrue(m_pgh.has_value()); auto& pgh = *m_pgh.get(); - Assert::AreEqual("zlib", pgh.core_paragraph.name.c_str()); - Assert::AreEqual("1.2.8", pgh.core_paragraph.version.c_str()); - Assert::AreEqual("", pgh.core_paragraph.maintainer.c_str()); - Assert::AreEqual("", pgh.core_paragraph.description.c_str()); - Assert::AreEqual(size_t(0), pgh.core_paragraph.depends.size()); + Assert::AreEqual("zlib", pgh->core_paragraph->name.c_str()); + Assert::AreEqual("1.2.8", pgh->core_paragraph->version.c_str()); + Assert::AreEqual("", pgh->core_paragraph->maintainer.c_str()); + Assert::AreEqual("", pgh->core_paragraph->description.c_str()); + Assert::AreEqual(size_t(0), pgh->core_paragraph->depends.size()); } TEST_METHOD(SourceParagraph_Construct_Maximum) @@ -54,14 +54,14 @@ namespace UnitTest1 Assert::IsTrue(m_pgh.has_value()); auto& pgh = *m_pgh.get(); - Assert::AreEqual("s", pgh.core_paragraph.name.c_str()); - Assert::AreEqual("v", pgh.core_paragraph.version.c_str()); - Assert::AreEqual("m", pgh.core_paragraph.maintainer.c_str()); - Assert::AreEqual("d", pgh.core_paragraph.description.c_str()); - Assert::AreEqual(size_t(1), pgh.core_paragraph.depends.size()); - Assert::AreEqual("bd", pgh.core_paragraph.depends[0].name.c_str()); - Assert::AreEqual(size_t(1), pgh.core_paragraph.supports.size()); - Assert::AreEqual("x64", pgh.core_paragraph.supports[0].c_str()); + Assert::AreEqual("s", pgh->core_paragraph->name.c_str()); + Assert::AreEqual("v", pgh->core_paragraph->version.c_str()); + Assert::AreEqual("m", pgh->core_paragraph->maintainer.c_str()); + Assert::AreEqual("d", pgh->core_paragraph->description.c_str()); + Assert::AreEqual(size_t(1), pgh->core_paragraph->depends.size()); + Assert::AreEqual("bd", pgh->core_paragraph->depends[0].name.c_str()); + Assert::AreEqual(size_t(1), pgh->core_paragraph->supports.size()); + Assert::AreEqual("x64", pgh->core_paragraph->supports[0].c_str()); } TEST_METHOD(SourceParagraph_Two_Depends) @@ -73,9 +73,9 @@ namespace UnitTest1 Assert::IsTrue(m_pgh.has_value()); auto& pgh = *m_pgh.get(); - Assert::AreEqual(size_t(2), pgh.core_paragraph.depends.size()); - Assert::AreEqual("z", pgh.core_paragraph.depends[0].name.c_str()); - Assert::AreEqual("openssl", pgh.core_paragraph.depends[1].name.c_str()); + Assert::AreEqual(size_t(2), pgh->core_paragraph->depends.size()); + Assert::AreEqual("z", pgh->core_paragraph->depends[0].name.c_str()); + Assert::AreEqual("openssl", pgh->core_paragraph->depends[1].name.c_str()); } TEST_METHOD(SourceParagraph_Three_Depends) @@ -87,10 +87,10 @@ namespace UnitTest1 Assert::IsTrue(m_pgh.has_value()); auto& pgh = *m_pgh.get(); - Assert::AreEqual(size_t(3), pgh.core_paragraph.depends.size()); - Assert::AreEqual("z", pgh.core_paragraph.depends[0].name.c_str()); - Assert::AreEqual("openssl", pgh.core_paragraph.depends[1].name.c_str()); - Assert::AreEqual("xyz", pgh.core_paragraph.depends[2].name.c_str()); + Assert::AreEqual(size_t(3), pgh->core_paragraph->depends.size()); + Assert::AreEqual("z", pgh->core_paragraph->depends[0].name.c_str()); + Assert::AreEqual("openssl", pgh->core_paragraph->depends[1].name.c_str()); + Assert::AreEqual("xyz", pgh->core_paragraph->depends[2].name.c_str()); } TEST_METHOD(SourceParagraph_Three_Supports) @@ -102,10 +102,10 @@ namespace UnitTest1 Assert::IsTrue(m_pgh.has_value()); auto& pgh = *m_pgh.get(); - Assert::AreEqual(size_t(3), pgh.core_paragraph.supports.size()); - Assert::AreEqual("x64", pgh.core_paragraph.supports[0].c_str()); - Assert::AreEqual("windows", pgh.core_paragraph.supports[1].c_str()); - Assert::AreEqual("uwp", pgh.core_paragraph.supports[2].c_str()); + Assert::AreEqual(size_t(3), pgh->core_paragraph->supports.size()); + Assert::AreEqual("x64", pgh->core_paragraph->supports[0].c_str()); + Assert::AreEqual("windows", pgh->core_paragraph->supports[1].c_str()); + Assert::AreEqual("uwp", pgh->core_paragraph->supports[2].c_str()); } TEST_METHOD(SourceParagraph_Construct_Qualified_Depends) @@ -117,15 +117,15 @@ namespace UnitTest1 Assert::IsTrue(m_pgh.has_value()); auto& pgh = *m_pgh.get(); - Assert::AreEqual("zlib", pgh.core_paragraph.name.c_str()); - Assert::AreEqual("1.2.8", pgh.core_paragraph.version.c_str()); - Assert::AreEqual("", pgh.core_paragraph.maintainer.c_str()); - Assert::AreEqual("", pgh.core_paragraph.description.c_str()); - Assert::AreEqual(size_t(2), pgh.core_paragraph.depends.size()); - Assert::AreEqual("libA", pgh.core_paragraph.depends[0].name.c_str()); - Assert::AreEqual("windows", pgh.core_paragraph.depends[0].qualifier.c_str()); - Assert::AreEqual("libB", pgh.core_paragraph.depends[1].name.c_str()); - Assert::AreEqual("uwp", pgh.core_paragraph.depends[1].qualifier.c_str()); + Assert::AreEqual("zlib", pgh->core_paragraph->name.c_str()); + Assert::AreEqual("1.2.8", pgh->core_paragraph->version.c_str()); + Assert::AreEqual("", pgh->core_paragraph->maintainer.c_str()); + Assert::AreEqual("", pgh->core_paragraph->description.c_str()); + Assert::AreEqual(size_t(2), pgh->core_paragraph->depends.size()); + Assert::AreEqual("libA", pgh->core_paragraph->depends[0].name.c_str()); + Assert::AreEqual("windows", pgh->core_paragraph->depends[0].qualifier.c_str()); + Assert::AreEqual("libB", pgh->core_paragraph->depends[1].name.c_str()); + Assert::AreEqual("uwp", pgh->core_paragraph->depends[1].qualifier.c_str()); } TEST_METHOD(BinaryParagraph_Construct_Minimum) diff --git a/toolsrc/src/vcpkg_Build.cpp b/toolsrc/src/vcpkg_Build.cpp index 0ca6dc243..a73d59910 100644 --- a/toolsrc/src/vcpkg_Build.cpp +++ b/toolsrc/src/vcpkg_Build.cpp @@ -11,7 +11,6 @@ #include "vcpkg_System.h" #include "vcpkg_optional.h" #include "vcpkglib.h" -#include "vcpkglib_helpers.h" namespace vcpkg::Build { @@ -218,56 +217,52 @@ namespace vcpkg::Build static BuildInfo inner_create_buildinfo(std::unordered_map<std::string, std::string> pgh) { + Parse::ParagraphParser parser(std::move(pgh)); + BuildInfo build_info; - const std::string crt_linkage_as_string = - details::remove_required_field(&pgh, BuildInfoRequiredField::CRT_LINKAGE); - - auto crtlinkage = to_linkage_type(crt_linkage_as_string); - if (auto p = crtlinkage.get()) - build_info.crt_linkage = *p; - else - Checks::exit_with_message(VCPKG_LINE_INFO, "Invalid crt linkage type: [%s]", crt_linkage_as_string); - - const std::string library_linkage_as_string = - details::remove_required_field(&pgh, BuildInfoRequiredField::LIBRARY_LINKAGE); - auto liblinkage = to_linkage_type(library_linkage_as_string); - if (auto p = liblinkage.get()) - build_info.library_linkage = *p; - else - Checks::exit_with_message(VCPKG_LINE_INFO, "Invalid library linkage type: [%s]", library_linkage_as_string); - - auto it_version = pgh.find("Version"); - if (it_version != pgh.end()) + { - build_info.version = it_version->second; - pgh.erase(it_version); + std::string crt_linkage_as_string; + parser.required_field(BuildInfoRequiredField::CRT_LINKAGE, crt_linkage_as_string); + + auto crtlinkage = to_linkage_type(crt_linkage_as_string); + if (auto p = crtlinkage.get()) + build_info.crt_linkage = *p; + else + Checks::exit_with_message(VCPKG_LINE_INFO, "Invalid crt linkage type: [%s]", crt_linkage_as_string); } - std::map<BuildPolicy, bool> policies; + { + std::string library_linkage_as_string; + parser.required_field(BuildInfoRequiredField::LIBRARY_LINKAGE, library_linkage_as_string); + auto liblinkage = to_linkage_type(library_linkage_as_string); + if (auto p = liblinkage.get()) + build_info.library_linkage = *p; + else + Checks::exit_with_message( + VCPKG_LINE_INFO, "Invalid library linkage type: [%s]", library_linkage_as_string); + } + build_info.version = parser.optional_field("Version"); - // The remaining entries are policies - for (const std::unordered_map<std::string, std::string>::value_type& p : pgh) + std::map<BuildPolicy, bool> policies; + for (auto policy : g_all_policies) { - auto maybe_policy = to_build_policy(p.first); - if (auto policy = maybe_policy.get()) - { - Checks::check_exit(VCPKG_LINE_INFO, - policies.find(*policy) == policies.end(), - "Policy specified multiple times: %s", - p.first); - - if (p.second == "enabled") - policies.emplace(*policy, true); - else if (p.second == "disabled") - policies.emplace(*policy, false); - else - Checks::exit_with_message( - VCPKG_LINE_INFO, "Unknown setting for policy '%s': %s", p.first, p.second); - } + const auto setting = parser.optional_field(to_string(policy)); + if (setting.empty()) + continue; + else if (setting == "enabled") + policies.emplace(policy, true); + else if (setting == "disabled") + policies.emplace(policy, false); else - { - Checks::exit_with_message(VCPKG_LINE_INFO, "Unknown policy found: %s", p.first); - } + Checks::exit_with_message( + VCPKG_LINE_INFO, "Unknown setting for policy '%s': %s", to_string(policy), setting); + } + + if (auto err = parser.error_info("PostBuildInformation")) + { + print_error_message(err); + Checks::exit_fail(VCPKG_LINE_INFO); } build_info.policies = BuildPolicies(std::move(policies)); diff --git a/toolsrc/src/vcpkg_Build_BuildPolicy.cpp b/toolsrc/src/vcpkg_Build_BuildPolicy.cpp index e75e176a2..b3bb778dc 100644 --- a/toolsrc/src/vcpkg_Build_BuildPolicy.cpp +++ b/toolsrc/src/vcpkg_Build_BuildPolicy.cpp @@ -12,17 +12,6 @@ namespace vcpkg::Build static const std::string NAME_EMPTY_INCLUDE_FOLDER = "PolicyEmptyIncludeFolder"; static const std::string NAME_ALLOW_OBSOLETE_MSVCRT = "PolicyAllowObsoleteMsvcrt"; - Optional<BuildPolicy> to_build_policy(const std::string& s) - { - if (s == NAME_EMPTY_PACKAGE) return BuildPolicy::EMPTY_PACKAGE; - if (s == NAME_DLLS_WITHOUT_LIBS) return BuildPolicy::DLLS_WITHOUT_LIBS; - if (s == NAME_ONLY_RELEASE_CRT) return BuildPolicy::ONLY_RELEASE_CRT; - if (s == NAME_EMPTY_INCLUDE_FOLDER) return BuildPolicy::EMPTY_INCLUDE_FOLDER; - if (s == NAME_ALLOW_OBSOLETE_MSVCRT) return BuildPolicy::ALLOW_OBSOLETE_MSVCRT; - - return nullopt; - } - const std::string& to_string(BuildPolicy policy) { switch (policy) diff --git a/toolsrc/src/vcpkg_Dependencies.cpp b/toolsrc/src/vcpkg_Dependencies.cpp index add8acb4d..bbf807c95 100644 --- a/toolsrc/src/vcpkg_Dependencies.cpp +++ b/toolsrc/src/vcpkg_Dependencies.cpp @@ -174,12 +174,11 @@ namespace vcpkg::Dependencies if (auto bpgh = maybe_bpgh.get()) return InstallPlanAction{spec, {nullopt, *bpgh, nullopt}, request_type}; - ExpectedT<SourceControlFile, ParseControlErrorInfo> source_control_file = - Paragraphs::try_load_port(paths.get_filesystem(), paths.port_dir(spec)); - if (auto scf = source_control_file.get()) - return InstallPlanAction{spec, {nullopt, nullopt, (*scf).core_paragraph}, request_type}; + auto maybe_scf = Paragraphs::try_load_port(paths.get_filesystem(), paths.port_dir(spec)); + if (auto scf = maybe_scf.get()) + return InstallPlanAction{spec, {nullopt, nullopt, *scf->get()->core_paragraph}, request_type}; - print_error_message(source_control_file.error()); + print_error_message(maybe_scf.error()); Checks::exit_fail(VCPKG_LINE_INFO); } }; @@ -284,13 +283,11 @@ namespace vcpkg::Dependencies if (auto bpgh = maybe_bpgh.get()) return ExportPlanAction{spec, {nullopt, *bpgh, nullopt}, request_type}; - ExpectedT<SourceControlFile, ParseControlErrorInfo> source_control_file = - Paragraphs::try_load_port(paths.get_filesystem(), paths.port_dir(spec)); - if (auto scf = source_control_file.get()) - return ExportPlanAction{spec, {nullopt, nullopt, (*scf).core_paragraph}, request_type}; - + auto maybe_scf = Paragraphs::try_load_port(paths.get_filesystem(), paths.port_dir(spec)); + if (auto scf = maybe_scf.get()) + return ExportPlanAction{spec, {nullopt, nullopt, *scf->get()->core_paragraph}, request_type}; else - print_error_message(source_control_file.error()); + print_error_message(maybe_scf.error()); Checks::exit_with_message(VCPKG_LINE_INFO, "Could not find package %s", spec); } diff --git a/toolsrc/src/vcpkg_Parse.cpp b/toolsrc/src/vcpkg_Parse.cpp new file mode 100644 index 000000000..b63ce41a9 --- /dev/null +++ b/toolsrc/src/vcpkg_Parse.cpp @@ -0,0 +1,59 @@ +#include "pch.h" + +#include "vcpkg_Checks.h" +#include "vcpkg_Maps.h" +#include "vcpkg_Parse.h" + +namespace vcpkg::Parse +{ + static Optional<std::string> get_field(const std::unordered_map<std::string, std::string>& fields, + const std::string& fieldname) + { + auto it = fields.find(fieldname); + if (it == fields.end()) + { + return nullopt; + } + + return it->second; + } + + static Optional<std::string> remove_field(std::unordered_map<std::string, std::string>* fields, + const std::string& fieldname) + { + auto it = fields->find(fieldname); + if (it == fields->end()) + { + return nullopt; + } + + const std::string value = std::move(it->second); + fields->erase(it); + return value; + } + + void ParagraphParser::required_field(const std::string& fieldname, std::string& out) + { + auto maybe_field = remove_field(&fields, fieldname); + if (auto field = maybe_field.get()) + out = std::move(*field); + else + missing_fields.push_back(fieldname); + } + std::string ParagraphParser::optional_field(const std::string& fieldname) + { + return remove_field(&fields, fieldname).value_or(""); + } + std::unique_ptr<ParseControlErrorInfo> ParagraphParser::error_info(const std::string& name) const + { + if (!fields.empty() || !missing_fields.empty()) + { + auto err = std::make_unique<ParseControlErrorInfo>(); + err->name = name; + err->extra_fields = Maps::extract_keys(fields); + err->missing_fields = std::move(missing_fields); + return err; + } + return nullptr; + } +} diff --git a/toolsrc/src/vcpkglib.cpp b/toolsrc/src/vcpkglib.cpp index 15130f77e..6b180b532 100644 --- a/toolsrc/src/vcpkglib.cpp +++ b/toolsrc/src/vcpkglib.cpp @@ -31,7 +31,7 @@ namespace vcpkg std::vector<std::unique_ptr<StatusParagraph>> status_pghs; for (auto&& p : pghs) { - status_pghs.push_back(std::make_unique<StatusParagraph>(p)); + status_pghs.push_back(std::make_unique<StatusParagraph>(std::move(p))); } return StatusParagraphs(std::move(status_pghs)); @@ -69,7 +69,7 @@ namespace vcpkg auto pghs = Paragraphs::get_paragraphs(fs, file).value_or_exit(VCPKG_LINE_INFO); for (auto&& p : pghs) { - current_status_db.insert(std::make_unique<StatusParagraph>(p)); + current_status_db.insert(std::make_unique<StatusParagraph>(std::move(p))); } } @@ -239,4 +239,10 @@ namespace vcpkg return Strings::wformat( LR"("%s" %s -P "%s")", cmake_exe.native(), cmd_cmake_pass_variables, cmake_script.generic_wstring()); } + + std::string shorten_description(const std::string& desc) + { + auto simple_desc = std::regex_replace(desc, std::regex("\\s+"), " "); + return simple_desc.size() <= 52 ? simple_desc : simple_desc.substr(0, 49) + "..."; + } } diff --git a/toolsrc/src/vcpkglib_helpers.cpp b/toolsrc/src/vcpkglib_helpers.cpp deleted file mode 100644 index 9f992d320..000000000 --- a/toolsrc/src/vcpkglib_helpers.cpp +++ /dev/null @@ -1,56 +0,0 @@ -#include "pch.h" - -#include "vcpkg_Checks.h" -#include "vcpkglib_helpers.h" - -namespace vcpkg::details -{ - std::string optional_field(const std::unordered_map<std::string, std::string>& fields, const std::string& fieldname) - { - auto it = fields.find(fieldname); - if (it == fields.end()) - { - return std::string(); - } - - return it->second; - } - - std::string remove_optional_field(std::unordered_map<std::string, std::string>* fields, - const std::string& fieldname) - { - auto it = fields->find(fieldname); - if (it == fields->end()) - { - return std::string(); - } - - const std::string value = std::move(it->second); - fields->erase(it); - return value; - } - - std::string required_field(const std::unordered_map<std::string, std::string>& fields, const std::string& fieldname) - { - auto it = fields.find(fieldname); - Checks::check_exit(VCPKG_LINE_INFO, it != fields.end(), "Required field not present: %s", fieldname); - return it->second; - } - - std::string remove_required_field(std::unordered_map<std::string, std::string>* fields, - const std::string& fieldname) - { - auto it = fields->find(fieldname); - Checks::check_exit(VCPKG_LINE_INFO, it != fields->end(), "Required field not present: %s", fieldname); - - const std::string value = std::move(it->second); - fields->erase(it); - return value; - } - - std::string shorten_description(const std::string& desc) - { - auto simple_desc = std::regex_replace(desc, std::regex("\\s+"), " "); - return simple_desc.size() <= 52 ? simple_desc : simple_desc.substr(0, 49) + "..."; - } -} diff --git a/toolsrc/vcpkglib/vcpkglib.vcxproj b/toolsrc/vcpkglib/vcpkglib.vcxproj index 487609cca..200f91d1c 100644 --- a/toolsrc/vcpkglib/vcpkglib.vcxproj +++ b/toolsrc/vcpkglib/vcpkglib.vcxproj @@ -161,7 +161,7 @@ <ClInclude Include="..\include\vcpkg_Chrono.h" /> <ClInclude Include="..\include\triplet.h" /> <ClInclude Include="..\include\vcpkglib.h" /> - <ClInclude Include="..\include\vcpkglib_helpers.h" /> + <ClInclude Include="..\include\vcpkg_Parse.h" /> <ClInclude Include="..\include\vcpkg_Checks.h" /> <ClInclude Include="..\include\VcpkgCmdArguments.h" /> <ClInclude Include="..\include\vcpkg_Commands.h" /> @@ -227,7 +227,7 @@ <ClCompile Include="..\src\StatusParagraph.cpp" /> <ClCompile Include="..\src\StatusParagraphs.cpp" /> <ClCompile Include="..\src\triplet.cpp" /> - <ClCompile Include="..\src\vcpkglib_helpers.cpp" /> + <ClCompile Include="..\src\vcpkg_Parse.cpp" /> <ClCompile Include="..\src\vcpkg_Checks.cpp" /> <ClCompile Include="..\src\VcpkgCmdArguments.cpp" /> <ClCompile Include="..\src\vcpkg_Dependencies.cpp" /> diff --git a/toolsrc/vcpkglib/vcpkglib.vcxproj.filters b/toolsrc/vcpkglib/vcpkglib.vcxproj.filters index a901cebe7..4f51dfa9a 100644 --- a/toolsrc/vcpkglib/vcpkglib.vcxproj.filters +++ b/toolsrc/vcpkglib/vcpkglib.vcxproj.filters @@ -30,9 +30,6 @@ <ClCompile Include="..\src\triplet.cpp"> <Filter>Source Files</Filter> </ClCompile> - <ClCompile Include="..\src\vcpkglib_helpers.cpp"> - <Filter>Source Files</Filter> - </ClCompile> <ClCompile Include="..\src\Paragraphs.cpp"> <Filter>Source Files</Filter> </ClCompile> @@ -177,14 +174,14 @@ <ClCompile Include="..\src\vcpkg_Build_BuildPolicy.cpp"> <Filter>Source Files</Filter> </ClCompile> + <ClCompile Include="..\src\vcpkg_Parse.cpp"> + <Filter>Source Files</Filter> + </ClCompile> </ItemGroup> <ItemGroup> <ClInclude Include="..\include\SourceParagraph.h"> <Filter>Header Files</Filter> </ClInclude> - <ClInclude Include="..\include\vcpkglib_helpers.h"> - <Filter>Header Files</Filter> - </ClInclude> <ClInclude Include="..\include\BinaryParagraph.h"> <Filter>Header Files</Filter> </ClInclude> @@ -302,5 +299,8 @@ <ClInclude Include="..\include\Span.h"> <Filter>Header Files</Filter> </ClInclude> + <ClInclude Include="..\include\vcpkg_Parse.h"> + <Filter>Header Files</Filter> + </ClInclude> </ItemGroup> </Project>
\ No newline at end of file |
