mirror of https://github.com/microsoft/vcpkg.git
Rework Paragraph parsing error handling. Add single paragraph functions
This commit is contained in:
parent
90bb4a2eeb
commit
d2bab3c370
|
|
@ -8,8 +8,10 @@
|
|||
|
||||
namespace vcpkg::Paragraphs
|
||||
{
|
||||
std::vector<std::unordered_map<std::string, std::string>> get_paragraphs(const fs::path& control_path);
|
||||
std::vector<std::unordered_map<std::string, std::string>> parse_paragraphs(const std::string& str);
|
||||
expected<std::unordered_map<std::string, std::string>> get_single_paragraph(const fs::path& control_path);
|
||||
expected<std::vector<std::unordered_map<std::string, std::string>>> get_paragraphs(const fs::path& control_path);
|
||||
expected<std::unordered_map<std::string, std::string>> parse_single_paragraph(const std::string& str);
|
||||
expected<std::vector<std::unordered_map<std::string, std::string>>> parse_paragraphs(const std::string& str);
|
||||
|
||||
expected<SourceParagraph> try_load_port(const fs::path& control_path);
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,35 @@
|
|||
#pragma once
|
||||
#include <system_error>
|
||||
|
||||
namespace vcpkg
|
||||
{
|
||||
enum class paragraph_parse_result
|
||||
{
|
||||
SUCCESS = 0,
|
||||
EXPECTED_ONE_PARAGRAPH
|
||||
};
|
||||
|
||||
struct paragraph_parse_result_category_impl 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(paragraph_parse_result e);
|
||||
|
||||
paragraph_parse_result to_paragraph_parse_result(int i);
|
||||
|
||||
paragraph_parse_result to_paragraph_parse_result(std::error_code ec);
|
||||
}
|
||||
|
||||
// Enable implicit conversion to std::error_code
|
||||
namespace std
|
||||
{
|
||||
template <>
|
||||
struct is_error_code_enum<vcpkg::paragraph_parse_result> : ::std::true_type
|
||||
{
|
||||
};
|
||||
}
|
||||
|
|
@ -1,6 +1,7 @@
|
|||
#include "pch.h"
|
||||
#include "Paragraphs.h"
|
||||
#include "vcpkg_Files.h"
|
||||
#include "paragraph_parse_result.h"
|
||||
|
||||
namespace vcpkg::Paragraphs
|
||||
{
|
||||
|
|
@ -150,7 +151,18 @@ namespace vcpkg::Paragraphs
|
|||
}
|
||||
};
|
||||
|
||||
std::vector<std::unordered_map<std::string, std::string>> get_paragraphs(const fs::path& control_path)
|
||||
expected<std::unordered_map<std::string, std::string>> get_single_paragraph(const fs::path& control_path)
|
||||
{
|
||||
const expected<std::string> contents = Files::read_contents(control_path);
|
||||
if (auto spgh = contents.get())
|
||||
{
|
||||
return parse_single_paragraph(*spgh);
|
||||
}
|
||||
|
||||
return contents.error_code();
|
||||
}
|
||||
|
||||
expected<std::vector<std::unordered_map<std::string, std::string>>> get_paragraphs(const fs::path& control_path)
|
||||
{
|
||||
const expected<std::string> contents = Files::read_contents(control_path);
|
||||
if (auto spgh = contents.get())
|
||||
|
|
@ -158,44 +170,47 @@ namespace vcpkg::Paragraphs
|
|||
return parse_paragraphs(*spgh);
|
||||
}
|
||||
|
||||
Checks::exit_with_message(VCPKG_LINE_INFO, "Error while reading %s: %s", control_path.generic_string(), contents.error_code().message());
|
||||
return contents.error_code();
|
||||
}
|
||||
|
||||
std::vector<std::unordered_map<std::string, std::string>> parse_paragraphs(const std::string& str)
|
||||
expected<std::unordered_map<std::string, std::string>> parse_single_paragraph(const std::string& str)
|
||||
{
|
||||
const std::vector<std::unordered_map<std::string, std::string>> p = Parser(str.c_str(), str.c_str() + str.size()).get_paragraphs();
|
||||
|
||||
if (p.size() == 1)
|
||||
{
|
||||
return p.at(0);
|
||||
}
|
||||
|
||||
return std::error_code(paragraph_parse_result::EXPECTED_ONE_PARAGRAPH);
|
||||
}
|
||||
|
||||
expected<std::vector<std::unordered_map<std::string, std::string>>> parse_paragraphs(const std::string& str)
|
||||
{
|
||||
return Parser(str.c_str(), str.c_str() + str.size()).get_paragraphs();
|
||||
}
|
||||
|
||||
expected<SourceParagraph> try_load_port(const fs::path& path)
|
||||
{
|
||||
try
|
||||
expected<std::unordered_map<std::string, std::string>> pghs = get_single_paragraph(path / "CONTROL");
|
||||
if (auto p = pghs.get())
|
||||
{
|
||||
auto pghs = get_paragraphs(path / "CONTROL");
|
||||
Checks::check_exit(VCPKG_LINE_INFO, pghs.size() == 1, "Invalid control file at %s\\CONTROL", path.string());
|
||||
return SourceParagraph(pghs[0]);
|
||||
return SourceParagraph(*p);
|
||||
}
|
||||
catch (std::runtime_error const&) {}
|
||||
|
||||
return std::errc::no_such_file_or_directory;
|
||||
return pghs.error_code();
|
||||
}
|
||||
|
||||
expected<BinaryParagraph> try_load_cached_package(const vcpkg_paths& paths, const package_spec& spec)
|
||||
{
|
||||
const fs::path path = paths.package_dir(spec) / "CONTROL";
|
||||
expected<std::unordered_map<std::string, std::string>> pghs = get_single_paragraph(paths.package_dir(spec) / "CONTROL");
|
||||
|
||||
auto control_contents_maybe = Files::read_contents(path);
|
||||
if (auto control_contents = control_contents_maybe.get())
|
||||
if (auto p = pghs.get())
|
||||
{
|
||||
std::vector<std::unordered_map<std::string, std::string>> pghs;
|
||||
try
|
||||
{
|
||||
pghs = parse_paragraphs(*control_contents);
|
||||
}
|
||||
catch (std::runtime_error) {}
|
||||
Checks::check_exit(VCPKG_LINE_INFO, pghs.size() == 1, "Invalid control file at %s", path.string());
|
||||
return BinaryParagraph(pghs[0]);
|
||||
return BinaryParagraph(*p);
|
||||
}
|
||||
return control_contents_maybe.error_code();
|
||||
|
||||
return pghs.error_code();
|
||||
}
|
||||
|
||||
std::vector<SourceParagraph> load_all_ports(const fs::path& ports_dir)
|
||||
|
|
|
|||
|
|
@ -39,10 +39,8 @@ namespace vcpkg::PostBuildLint
|
|||
|
||||
BuildInfo read_build_info(const fs::path& filepath)
|
||||
{
|
||||
const std::vector<std::unordered_map<std::string, std::string>> pghs = Paragraphs::get_paragraphs(filepath);
|
||||
Checks::check_exit(VCPKG_LINE_INFO, pghs.size() == 1, "Invalid BUILD_INFO file for package");
|
||||
|
||||
return BuildInfo::create(pghs[0]);
|
||||
const expected<std::unordered_map<std::string, std::string>> pghs = Paragraphs::get_single_paragraph(filepath);
|
||||
Checks::check_exit(VCPKG_LINE_INFO, pghs.get() != nullptr, "Invalid BUILD_INFO file for package");
|
||||
return BuildInfo::create(*pghs.get());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,22 +13,11 @@ namespace vcpkg::Commands::Cache
|
|||
for (auto it = fs::directory_iterator(paths.packages); it != fs::directory_iterator(); ++it)
|
||||
{
|
||||
const fs::path& path = it->path();
|
||||
|
||||
try
|
||||
{
|
||||
auto file_contents = Files::read_contents(path / "CONTROL");
|
||||
if (auto text = file_contents.get())
|
||||
{
|
||||
auto pghs = Paragraphs::parse_paragraphs(*text);
|
||||
if (pghs.size() != 1)
|
||||
continue;
|
||||
|
||||
const BinaryParagraph binary_paragraph = BinaryParagraph(pghs[0]);
|
||||
output.push_back(binary_paragraph);
|
||||
}
|
||||
}
|
||||
catch (std::runtime_error const&)
|
||||
const expected<std::unordered_map<std::string, std::string>> pghs = Paragraphs::get_single_paragraph(path / "CONTROL");
|
||||
if (auto p = pghs.get())
|
||||
{
|
||||
const BinaryParagraph binary_paragraph = BinaryParagraph(*p);
|
||||
output.push_back(binary_paragraph);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -72,11 +72,11 @@ namespace vcpkg::Commands::Import
|
|||
const fs::path include_directory(args.command_arguments[1]);
|
||||
const fs::path project_directory(args.command_arguments[2]);
|
||||
|
||||
auto pghs = Paragraphs::get_paragraphs(control_file_path);
|
||||
Checks::check_exit(VCPKG_LINE_INFO, pghs.size() == 1, "Invalid control file %s for package", control_file_path.generic_string());
|
||||
const expected<std::unordered_map<std::string, std::string>> pghs = Paragraphs::get_single_paragraph(control_file_path);
|
||||
Checks::check_exit(VCPKG_LINE_INFO, pghs.get() != nullptr, "Invalid control file %s for package", control_file_path.generic_string());
|
||||
|
||||
StatusParagraph spgh;
|
||||
spgh.package = BinaryParagraph(pghs[0]);
|
||||
spgh.package = BinaryParagraph(*pghs.get());
|
||||
auto& control_file_data = spgh.package;
|
||||
|
||||
do_import(paths, include_directory, project_directory, control_file_data);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,45 @@
|
|||
#include "pch.h"
|
||||
#include "vcpkg_Checks.h"
|
||||
#include "paragraph_parse_result.h"
|
||||
|
||||
namespace vcpkg
|
||||
{
|
||||
const char* paragraph_parse_result_category_impl::name() const noexcept
|
||||
{
|
||||
return "paragraph_parse_result";
|
||||
}
|
||||
|
||||
std::string paragraph_parse_result_category_impl::message(int ev) const noexcept
|
||||
{
|
||||
switch (static_cast<paragraph_parse_result>(ev))
|
||||
{
|
||||
case paragraph_parse_result::SUCCESS:
|
||||
return "OK";
|
||||
case paragraph_parse_result::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 paragraph_parse_result_category_impl instance;
|
||||
return instance;
|
||||
}
|
||||
|
||||
std::error_code make_error_code(paragraph_parse_result e)
|
||||
{
|
||||
return std::error_code(static_cast<int>(e), paragraph_parse_result_category());
|
||||
}
|
||||
|
||||
paragraph_parse_result to_paragraph_parse_result(int i)
|
||||
{
|
||||
return static_cast<paragraph_parse_result>(i);
|
||||
}
|
||||
|
||||
paragraph_parse_result to_paragraph_parse_result(std::error_code ec)
|
||||
{
|
||||
return to_paragraph_parse_result(ec.value());
|
||||
}
|
||||
}
|
||||
|
|
@ -153,14 +153,14 @@ namespace UnitTest1
|
|||
TEST_METHOD(parse_paragraphs_empty)
|
||||
{
|
||||
const char* str = "";
|
||||
auto pghs = vcpkg::Paragraphs::parse_paragraphs(str);
|
||||
auto pghs = vcpkg::Paragraphs::parse_paragraphs(str).get_or_throw(VCPKG_LINE_INFO);
|
||||
Assert::IsTrue(pghs.empty());
|
||||
}
|
||||
|
||||
TEST_METHOD(parse_paragraphs_one_field)
|
||||
{
|
||||
const char* str = "f1: v1";
|
||||
auto pghs = vcpkg::Paragraphs::parse_paragraphs(str);
|
||||
auto pghs = vcpkg::Paragraphs::parse_paragraphs(str).get_or_throw(VCPKG_LINE_INFO);
|
||||
Assert::AreEqual(size_t(1), pghs.size());
|
||||
Assert::AreEqual(size_t(1), pghs[0].size());
|
||||
Assert::AreEqual("v1", pghs[0]["f1"].c_str());
|
||||
|
|
@ -171,7 +171,7 @@ namespace UnitTest1
|
|||
const char* str =
|
||||
"f1: v1\n"
|
||||
"f2: v2";
|
||||
auto pghs = vcpkg::Paragraphs::parse_paragraphs(str);
|
||||
auto pghs = vcpkg::Paragraphs::parse_paragraphs(str).get_or_throw(VCPKG_LINE_INFO);
|
||||
Assert::AreEqual(size_t(1), pghs.size());
|
||||
Assert::AreEqual(size_t(2), pghs[0].size());
|
||||
Assert::AreEqual("v1", pghs[0]["f1"].c_str());
|
||||
|
|
@ -186,7 +186,7 @@ namespace UnitTest1
|
|||
"\n"
|
||||
"f3: v3\n"
|
||||
"f4: v4";
|
||||
auto pghs = vcpkg::Paragraphs::parse_paragraphs(str);
|
||||
auto pghs = vcpkg::Paragraphs::parse_paragraphs(str).get_or_throw(VCPKG_LINE_INFO);
|
||||
Assert::AreEqual(size_t(2), pghs.size());
|
||||
Assert::AreEqual(size_t(2), pghs[0].size());
|
||||
Assert::AreEqual("v1", pghs[0]["f1"].c_str());
|
||||
|
|
@ -204,7 +204,7 @@ namespace UnitTest1
|
|||
"F:\n"
|
||||
"0:\n"
|
||||
"F-2:\n";
|
||||
auto pghs = vcpkg::Paragraphs::parse_paragraphs(str);
|
||||
auto pghs = vcpkg::Paragraphs::parse_paragraphs(str).get_or_throw(VCPKG_LINE_INFO);
|
||||
Assert::AreEqual(size_t(1), pghs.size());
|
||||
Assert::AreEqual(size_t(5), pghs[0].size());
|
||||
}
|
||||
|
|
@ -218,7 +218,7 @@ namespace UnitTest1
|
|||
"\n"
|
||||
"f3: v3\n"
|
||||
"f4: v4";
|
||||
auto pghs = vcpkg::Paragraphs::parse_paragraphs(str);
|
||||
auto pghs = vcpkg::Paragraphs::parse_paragraphs(str).get_or_throw(VCPKG_LINE_INFO);
|
||||
Assert::AreEqual(size_t(2), pghs.size());
|
||||
}
|
||||
|
||||
|
|
@ -227,7 +227,7 @@ namespace UnitTest1
|
|||
const char* str =
|
||||
"f1:\n"
|
||||
"f2: ";
|
||||
auto pghs = vcpkg::Paragraphs::parse_paragraphs(str);
|
||||
auto pghs = vcpkg::Paragraphs::parse_paragraphs(str).get_or_throw(VCPKG_LINE_INFO);
|
||||
Assert::AreEqual(size_t(1), pghs.size());
|
||||
Assert::AreEqual(size_t(2), pghs[0].size());
|
||||
Assert::AreEqual("", pghs[0]["f1"].c_str());
|
||||
|
|
@ -243,7 +243,7 @@ namespace UnitTest1
|
|||
"f2:\r\n"
|
||||
" f2\r\n"
|
||||
" continue\r\n";
|
||||
auto pghs = vcpkg::Paragraphs::parse_paragraphs(str);
|
||||
auto pghs = vcpkg::Paragraphs::parse_paragraphs(str).get_or_throw(VCPKG_LINE_INFO);
|
||||
Assert::AreEqual(size_t(1), pghs.size());
|
||||
Assert::AreEqual("simple\n f1", pghs[0]["f1"].c_str());
|
||||
Assert::AreEqual("\n f2\n continue", pghs[0]["f2"].c_str());
|
||||
|
|
@ -257,7 +257,7 @@ namespace UnitTest1
|
|||
"\r\n"
|
||||
"f3: v3\r\n"
|
||||
"f4: v4";
|
||||
auto pghs = vcpkg::Paragraphs::parse_paragraphs(str);
|
||||
auto pghs = vcpkg::Paragraphs::parse_paragraphs(str).get_or_throw(VCPKG_LINE_INFO);
|
||||
Assert::AreEqual(size_t(2), pghs.size());
|
||||
Assert::AreEqual(size_t(2), pghs[0].size());
|
||||
Assert::AreEqual("v1", pghs[0]["f1"].c_str());
|
||||
|
|
@ -277,7 +277,7 @@ namespace UnitTest1
|
|||
{"Multi-Arch", "same"},
|
||||
});
|
||||
ss << pgh;
|
||||
auto pghs = vcpkg::Paragraphs::parse_paragraphs(ss.str());
|
||||
auto pghs = vcpkg::Paragraphs::parse_paragraphs(ss.str()).get_or_throw(VCPKG_LINE_INFO);
|
||||
Assert::AreEqual(size_t(1), pghs.size());
|
||||
Assert::AreEqual(size_t(4), pghs[0].size());
|
||||
Assert::AreEqual("zlib", pghs[0]["Package"].c_str());
|
||||
|
|
@ -299,7 +299,7 @@ namespace UnitTest1
|
|||
{"Multi-Arch", "same"},
|
||||
});
|
||||
ss << pgh;
|
||||
auto pghs = vcpkg::Paragraphs::parse_paragraphs(ss.str());
|
||||
auto pghs = vcpkg::Paragraphs::parse_paragraphs(ss.str()).get_or_throw(VCPKG_LINE_INFO);
|
||||
Assert::AreEqual(size_t(1), pghs.size());
|
||||
Assert::AreEqual(size_t(7), pghs[0].size());
|
||||
Assert::AreEqual("zlib", pghs[0]["Package"].c_str());
|
||||
|
|
@ -321,7 +321,7 @@ namespace UnitTest1
|
|||
{"Depends", "a, b, c"},
|
||||
});
|
||||
ss << pgh;
|
||||
auto pghs = vcpkg::Paragraphs::parse_paragraphs(ss.str());
|
||||
auto pghs = vcpkg::Paragraphs::parse_paragraphs(ss.str()).get_or_throw(VCPKG_LINE_INFO);
|
||||
Assert::AreEqual(size_t(1), pghs.size());
|
||||
Assert::AreEqual("a, b, c", pghs[0]["Depends"].c_str());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -111,10 +111,8 @@ static void loadConfig()
|
|||
|
||||
try
|
||||
{
|
||||
std::string config_contents = Files::read_contents(localappdata / "vcpkg" / "config").get_or_throw(VCPKG_LINE_INFO);
|
||||
|
||||
auto pghs = Paragraphs::get_paragraphs(localappdata / "vcpkg" / "config").get_or_throw(VCPKG_LINE_INFO);
|
||||
std::unordered_map<std::string, std::string> keys;
|
||||
auto pghs = Paragraphs::parse_paragraphs(config_contents);
|
||||
if (pghs.size() > 0)
|
||||
keys = pghs[0];
|
||||
|
||||
|
|
|
|||
|
|
@ -22,8 +22,7 @@ namespace vcpkg
|
|||
fs::rename(vcpkg_dir_status_file_old, vcpkg_dir_status_file);
|
||||
}
|
||||
|
||||
auto text = Files::read_contents(vcpkg_dir_status_file).get_or_throw(VCPKG_LINE_INFO);
|
||||
auto pghs = Paragraphs::parse_paragraphs(text);
|
||||
auto pghs = Paragraphs::get_paragraphs(vcpkg_dir_status_file).get_or_throw(VCPKG_LINE_INFO);
|
||||
|
||||
std::vector<std::unique_ptr<StatusParagraph>> status_pghs;
|
||||
for (auto&& p : pghs)
|
||||
|
|
@ -65,8 +64,7 @@ namespace vcpkg
|
|||
if (b->path().filename() == "incomplete")
|
||||
continue;
|
||||
|
||||
auto text = Files::read_contents(b->path()).get_or_throw(VCPKG_LINE_INFO);
|
||||
auto pghs = Paragraphs::parse_paragraphs(text);
|
||||
auto pghs = Paragraphs::get_paragraphs(b->path()).get_or_throw(VCPKG_LINE_INFO);
|
||||
for (auto&& p : pghs)
|
||||
{
|
||||
current_status_db.insert(std::make_unique<StatusParagraph>(p));
|
||||
|
|
|
|||
|
|
@ -139,6 +139,7 @@
|
|||
<ClInclude Include="..\include\BinaryParagraph.h" />
|
||||
<ClInclude Include="..\include\lazy.h" />
|
||||
<ClInclude Include="..\include\LineInfo.h" />
|
||||
<ClInclude Include="..\include\paragraph_parse_result.h" />
|
||||
<ClInclude Include="..\include\PostBuildLint_BuildInfo.h" />
|
||||
<ClInclude Include="..\include\PostBuildLint_BuildPolicies.h" />
|
||||
<ClInclude Include="..\include\coff_file_reader.h" />
|
||||
|
|
@ -183,6 +184,7 @@
|
|||
<ClCompile Include="..\src\BinaryParagraph.cpp" />
|
||||
<ClCompile Include="..\src\commands_ci.cpp" />
|
||||
<ClCompile Include="..\src\LineInfo.cpp" />
|
||||
<ClCompile Include="..\src\paragraph_parse_result.cpp" />
|
||||
<ClCompile Include="..\src\PostBuildLint_BuildInfo.cpp" />
|
||||
<ClCompile Include="..\src\PostBuildLint_BuildPolicies.cpp" />
|
||||
<ClCompile Include="..\src\coff_file_reader.cpp" />
|
||||
|
|
|
|||
|
|
@ -174,6 +174,9 @@
|
|||
<ClCompile Include="..\src\LineInfo.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\paragraph_parse_result.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\include\package_spec.h">
|
||||
|
|
@ -302,5 +305,8 @@
|
|||
<ClInclude Include="..\include\LineInfo.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\include\paragraph_parse_result.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
Loading…
Reference in New Issue