[vcpkg] Restore layering and purge unused ParagraphParseResult (#12897)

Co-authored-by: Robert Schumacher <roschuma@microsoft.com>
This commit is contained in:
ras0219 2020-08-14 11:05:18 -07:00 committed by GitHub
parent 7c5ea94190
commit 74ab3aae01
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 129 additions and 200 deletions

View File

@ -1,36 +0,0 @@
#pragma once
#include <system_error>
namespace vcpkg
{
enum class ParagraphParseResult
{
SUCCESS = 0,
EXPECTED_ONE_PARAGRAPH
};
struct ParagraphParseResultCategoryImpl final : std::error_category
{
virtual const char* name() const noexcept override;
virtual std::string message(int ev) const noexcept override;
};
const std::error_category& paragraph_parse_result_category();
std::error_code make_error_code(ParagraphParseResult e);
ParagraphParseResult to_paragraph_parse_result(int i);
ParagraphParseResult to_paragraph_parse_result(std::error_code ec);
}
namespace std
{
// Enable implicit conversion to std::error_code
template<>
struct is_error_code_enum<vcpkg::ParagraphParseResult> : ::std::true_type
{
};
}

View File

@ -2,9 +2,6 @@
#include <vcpkg/base/system.print.h>
#include <vcpkg/base/util.h>
#include <vcpkg/packagespec.h>
#include <vcpkg/paragraphparser.h>
#include <utility>
using namespace vcpkg;
@ -104,128 +101,4 @@ namespace vcpkg::Parse
// Avoid error loops by skipping to the end
skip_to_eof();
}
static Optional<std::pair<std::string, TextRowCol>> remove_field(Paragraph* fields, const std::string& fieldname)
{
auto it = fields->find(fieldname);
if (it == fields->end())
{
return nullopt;
}
auto value = std::move(it->second);
fields->erase(it);
return value;
}
void ParagraphParser::required_field(const std::string& fieldname, std::pair<std::string&, TextRowCol&> out)
{
auto maybe_field = remove_field(&fields, fieldname);
if (const auto field = maybe_field.get())
out = std::move(*field);
else
missing_fields.push_back(fieldname);
}
void ParagraphParser::optional_field(const std::string& fieldname, std::pair<std::string&, TextRowCol&> out)
{
auto maybe_field = remove_field(&fields, fieldname);
if (auto field = maybe_field.get()) out = std::move(*field);
}
void ParagraphParser::required_field(const std::string& fieldname, std::string& out)
{
TextRowCol ignore;
required_field(fieldname, {out, ignore});
}
std::string ParagraphParser::optional_field(const std::string& fieldname)
{
std::string out;
TextRowCol ignore;
optional_field(fieldname, {out, ignore});
return out;
}
std::string ParagraphParser::required_field(const std::string& fieldname)
{
std::string out;
TextRowCol ignore;
required_field(fieldname, {out, ignore});
return out;
}
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["CONTROL"] = Util::extract_keys(fields);
err->missing_fields["CONTROL"] = std::move(missing_fields);
err->expected_types = std::move(expected_types);
return err;
}
return nullptr;
}
template<class T, class F>
static Optional<std::vector<T>> parse_list_until_eof(StringLiteral plural_item_name, Parse::ParserBase& parser, F f)
{
std::vector<T> ret;
parser.skip_whitespace();
if (parser.at_eof()) return std::vector<T>{};
do
{
auto item = f(parser);
if (!item) return nullopt;
ret.push_back(std::move(item).value_or_exit(VCPKG_LINE_INFO));
parser.skip_whitespace();
if (parser.at_eof()) return {std::move(ret)};
if (parser.cur() != ',')
{
parser.add_error(Strings::concat("expected ',' or end of text in ", plural_item_name, " list"));
return nullopt;
}
parser.next();
parser.skip_whitespace();
} while (true);
}
ExpectedS<std::vector<std::string>> parse_default_features_list(const std::string& str,
StringView origin,
TextRowCol textrowcol)
{
auto parser = Parse::ParserBase(str, origin, textrowcol);
auto opt = parse_list_until_eof<std::string>("default features", parser, &parse_feature_name);
if (!opt) return {parser.get_error()->format(), expected_right_tag};
return {std::move(opt).value_or_exit(VCPKG_LINE_INFO), expected_left_tag};
}
ExpectedS<std::vector<ParsedQualifiedSpecifier>> parse_qualified_specifier_list(const std::string& str,
StringView origin,
TextRowCol textrowcol)
{
auto parser = Parse::ParserBase(str, origin, textrowcol);
auto opt = parse_list_until_eof<ParsedQualifiedSpecifier>(
"dependencies", parser, [](ParserBase& parser) { return parse_qualified_specifier(parser); });
if (!opt) return {parser.get_error()->format(), expected_right_tag};
return {std::move(opt).value_or_exit(VCPKG_LINE_INFO), expected_left_tag};
}
ExpectedS<std::vector<Dependency>> parse_dependencies_list(const std::string& str,
StringView origin,
TextRowCol textrowcol)
{
auto parser = Parse::ParserBase(str, origin, textrowcol);
auto opt = parse_list_until_eof<Dependency>("dependencies", parser, [](ParserBase& parser) {
auto loc = parser.cur_loc();
return parse_qualified_specifier(parser).then([&](ParsedQualifiedSpecifier&& pqs) -> Optional<Dependency> {
if (pqs.triplet)
{
parser.add_error("triplet specifier not allowed in this context", loc);
return nullopt;
}
return Dependency{pqs.name, pqs.features.value_or({}), pqs.platform.value_or({})};
});
});
if (!opt) return {parser.get_error()->format(), expected_right_tag};
return {std::move(opt).value_or_exit(VCPKG_LINE_INFO), expected_left_tag};
}
}

View File

@ -1,33 +0,0 @@
#include <vcpkg/base/checks.h>
#include <vcpkg/paragraphparseresult.h>
namespace vcpkg
{
const char* ParagraphParseResultCategoryImpl::name() const noexcept { return "ParagraphParseResult"; }
std::string ParagraphParseResultCategoryImpl::message(int ev) const noexcept
{
switch (static_cast<ParagraphParseResult>(ev))
{
case ParagraphParseResult::SUCCESS: return "OK";
case ParagraphParseResult::EXPECTED_ONE_PARAGRAPH: return "There should be exactly one paragraph";
default: Checks::unreachable(VCPKG_LINE_INFO);
}
}
const std::error_category& paragraph_parse_result_category()
{
static ParagraphParseResultCategoryImpl instance;
return instance;
}
std::error_code make_error_code(ParagraphParseResult e)
{
return std::error_code(static_cast<int>(e), paragraph_parse_result_category());
}
ParagraphParseResult to_paragraph_parse_result(int i) { return static_cast<ParagraphParseResult>(i); }
ParagraphParseResult to_paragraph_parse_result(std::error_code ec) { return to_paragraph_parse_result(ec.value()); }
}

View File

@ -5,12 +5,139 @@
#include <vcpkg/base/util.h>
#include <vcpkg/binaryparagraph.h>
#include <vcpkg/paragraphparseresult.h>
#include <vcpkg/paragraphparser.h>
#include <vcpkg/paragraphs.h>
using namespace vcpkg::Parse;
using namespace vcpkg;
namespace vcpkg::Parse
{
static Optional<std::pair<std::string, TextRowCol>> remove_field(Paragraph* fields, const std::string& fieldname)
{
auto it = fields->find(fieldname);
if (it == fields->end())
{
return nullopt;
}
auto value = std::move(it->second);
fields->erase(it);
return value;
}
void ParagraphParser::required_field(const std::string& fieldname, std::pair<std::string&, TextRowCol&> out)
{
auto maybe_field = remove_field(&fields, fieldname);
if (const auto field = maybe_field.get())
out = std::move(*field);
else
missing_fields.push_back(fieldname);
}
void ParagraphParser::optional_field(const std::string& fieldname, std::pair<std::string&, TextRowCol&> out)
{
auto maybe_field = remove_field(&fields, fieldname);
if (auto field = maybe_field.get()) out = std::move(*field);
}
void ParagraphParser::required_field(const std::string& fieldname, std::string& out)
{
TextRowCol ignore;
required_field(fieldname, {out, ignore});
}
std::string ParagraphParser::optional_field(const std::string& fieldname)
{
std::string out;
TextRowCol ignore;
optional_field(fieldname, {out, ignore});
return out;
}
std::string ParagraphParser::required_field(const std::string& fieldname)
{
std::string out;
TextRowCol ignore;
required_field(fieldname, {out, ignore});
return out;
}
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["CONTROL"] = Util::extract_keys(fields);
err->missing_fields["CONTROL"] = std::move(missing_fields);
err->expected_types = std::move(expected_types);
return err;
}
return nullptr;
}
template<class T, class F>
static Optional<std::vector<T>> parse_list_until_eof(StringLiteral plural_item_name, Parse::ParserBase& parser, F f)
{
std::vector<T> ret;
parser.skip_whitespace();
if (parser.at_eof()) return std::vector<T>{};
do
{
auto item = f(parser);
if (!item) return nullopt;
ret.push_back(std::move(item).value_or_exit(VCPKG_LINE_INFO));
parser.skip_whitespace();
if (parser.at_eof()) return {std::move(ret)};
if (parser.cur() != ',')
{
parser.add_error(Strings::concat("expected ',' or end of text in ", plural_item_name, " list"));
return nullopt;
}
parser.next();
parser.skip_whitespace();
} while (true);
}
ExpectedS<std::vector<std::string>> parse_default_features_list(const std::string& str,
StringView origin,
TextRowCol textrowcol)
{
auto parser = Parse::ParserBase(str, origin, textrowcol);
auto opt = parse_list_until_eof<std::string>("default features", parser, &parse_feature_name);
if (!opt) return {parser.get_error()->format(), expected_right_tag};
return {std::move(opt).value_or_exit(VCPKG_LINE_INFO), expected_left_tag};
}
ExpectedS<std::vector<ParsedQualifiedSpecifier>> parse_qualified_specifier_list(const std::string& str,
StringView origin,
TextRowCol textrowcol)
{
auto parser = Parse::ParserBase(str, origin, textrowcol);
auto opt = parse_list_until_eof<ParsedQualifiedSpecifier>(
"dependencies", parser, [](ParserBase& parser) { return parse_qualified_specifier(parser); });
if (!opt) return {parser.get_error()->format(), expected_right_tag};
return {std::move(opt).value_or_exit(VCPKG_LINE_INFO), expected_left_tag};
}
ExpectedS<std::vector<Dependency>> parse_dependencies_list(const std::string& str,
StringView origin,
TextRowCol textrowcol)
{
auto parser = Parse::ParserBase(str, origin, textrowcol);
auto opt = parse_list_until_eof<Dependency>("dependencies", parser, [](ParserBase& parser) {
auto loc = parser.cur_loc();
return parse_qualified_specifier(parser).then([&](ParsedQualifiedSpecifier&& pqs) -> Optional<Dependency> {
if (pqs.triplet)
{
parser.add_error("triplet specifier not allowed in this context", loc);
return nullopt;
}
return Dependency{pqs.name, pqs.features.value_or({}), pqs.platform.value_or({})};
});
});
if (!opt) return {parser.get_error()->format(), expected_right_tag};
return {std::move(opt).value_or_exit(VCPKG_LINE_INFO), expected_left_tag};
}
}
namespace vcpkg::Paragraphs
{
struct PghParser : private Parse::ParserBase
@ -91,7 +218,7 @@ namespace vcpkg::Paragraphs
if (auto p = pghs.get())
{
if (p->size() != 1) return std::error_code(ParagraphParseResult::EXPECTED_ONE_PARAGRAPH).message();
if (p->size() != 1) return {"There should be exactly one paragraph", expected_right_tag};
return std::move(p->front());
}
else

View File

@ -222,7 +222,6 @@
<ClInclude Include="..\..\include\vcpkg\metrics.h" />
<ClInclude Include="..\..\include\vcpkg\packagespec.h" />
<ClInclude Include="..\..\include\vcpkg\paragraphparser.h" />
<ClInclude Include="..\..\include\vcpkg\paragraphparseresult.h" />
<ClInclude Include="..\..\include\vcpkg\paragraphs.h" />
<ClInclude Include="..\..\include\vcpkg\portfileprovider.h" />
<ClInclude Include="..\..\include\vcpkg\postbuildlint.h" />
@ -308,7 +307,6 @@
<ClCompile Include="..\..\src\vcpkg\platform-expression.cpp" />
<ClCompile Include="..\..\src\vcpkg\metrics.cpp" />
<ClCompile Include="..\..\src\vcpkg\packagespec.cpp" />
<ClCompile Include="..\..\src\vcpkg\paragraphparseresult.cpp" />
<ClCompile Include="..\..\src\vcpkg\paragraphs.cpp" />
<ClCompile Include="..\..\src\vcpkg\portfileprovider.cpp" />
<ClCompile Include="..\..\src\vcpkg\postbuildlint.buildtype.cpp" />