diff options
| author | Robert Schumacher <roschuma@microsoft.com> | 2020-02-09 14:50:26 -0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2020-02-09 14:50:26 -0800 |
| commit | a33044c18637d3df6de93128d33dae1fb5ba575c (patch) | |
| tree | 273838dd27daed933e63bc7d29a28b569557755f /toolsrc/src | |
| parent | 039098c9546195a50e45c41e37d7e2b9168b4245 (diff) | |
| download | vcpkg-a33044c18637d3df6de93128d33dae1fb5ba575c.tar.gz vcpkg-a33044c18637d3df6de93128d33dae1fb5ba575c.zip | |
[vcpkg] Track parser row/col state in Paragraph (renamed from RawParagraph) (#9987)
Diffstat (limited to 'toolsrc/src')
| -rw-r--r-- | toolsrc/src/vcpkg-test/paragraph.cpp | 184 | ||||
| -rw-r--r-- | toolsrc/src/vcpkg-test/statusparagraphs.cpp | 8 | ||||
| -rw-r--r-- | toolsrc/src/vcpkg-test/update.cpp | 8 | ||||
| -rw-r--r-- | toolsrc/src/vcpkg-test/util.cpp | 31 | ||||
| -rw-r--r-- | toolsrc/src/vcpkg/binaryparagraph.cpp | 2 | ||||
| -rw-r--r-- | toolsrc/src/vcpkg/build.cpp | 4 | ||||
| -rw-r--r-- | toolsrc/src/vcpkg/commands.ci.cpp | 6 | ||||
| -rw-r--r-- | toolsrc/src/vcpkg/paragraphs.cpp | 22 | ||||
| -rw-r--r-- | toolsrc/src/vcpkg/parse.cpp | 87 | ||||
| -rw-r--r-- | toolsrc/src/vcpkg/sourceparagraph.cpp | 28 | ||||
| -rw-r--r-- | toolsrc/src/vcpkg/statusparagraph.cpp | 4 | ||||
| -rw-r--r-- | toolsrc/src/vcpkg/userconfig.cpp | 10 |
12 files changed, 229 insertions, 165 deletions
diff --git a/toolsrc/src/vcpkg-test/paragraph.cpp b/toolsrc/src/vcpkg-test/paragraph.cpp index 21da80c5b..ba929ac56 100644 --- a/toolsrc/src/vcpkg-test/paragraph.cpp +++ b/toolsrc/src/vcpkg-test/paragraph.cpp @@ -6,15 +6,35 @@ #include <vcpkg/paragraphs.h> namespace Strings = vcpkg::Strings; +using vcpkg::Parse::Paragraph; + +auto test_parse_control_file(const std::vector<std::unordered_map<std::string, std::string>>& v) +{ + std::vector<Paragraph> pghs; + for (auto&& p : v) + { + pghs.emplace_back(); + for (auto&& kv : p) + pghs.back().emplace(kv.first, std::make_pair(kv.second, vcpkg::Parse::TextRowCol{})); + } + return vcpkg::SourceControlFile::parse_control_file("", std::move(pghs)); +} + +auto test_make_binary_paragraph(const std::unordered_map<std::string, std::string>& v) +{ + Paragraph pgh; + for (auto&& kv : v) + pgh.emplace(kv.first, std::make_pair(kv.second, vcpkg::Parse::TextRowCol{})); + + return vcpkg::BinaryParagraph(std::move(pgh)); +} TEST_CASE ("SourceParagraph construct minimum", "[paragraph]") { - auto m_pgh = - vcpkg::SourceControlFile::parse_control_file("", - std::vector<std::unordered_map<std::string, std::string>>{{ - {"Source", "zlib"}, - {"Version", "1.2.8"}, - }}); + auto m_pgh = test_parse_control_file({{ + {"Source", "zlib"}, + {"Version", "1.2.8"}, + }}); REQUIRE(m_pgh.has_value()); auto& pgh = **m_pgh.get(); @@ -28,16 +48,14 @@ TEST_CASE ("SourceParagraph construct minimum", "[paragraph]") TEST_CASE ("SourceParagraph construct maximum", "[paragraph]") { - auto m_pgh = - vcpkg::SourceControlFile::parse_control_file("", - std::vector<std::unordered_map<std::string, std::string>>{{ - {"Source", "s"}, - {"Version", "v"}, - {"Maintainer", "m"}, - {"Description", "d"}, - {"Build-Depends", "bd"}, - {"Default-Features", "df"}, - }}); + auto m_pgh = test_parse_control_file({{ + {"Source", "s"}, + {"Version", "v"}, + {"Maintainer", "m"}, + {"Description", "d"}, + {"Build-Depends", "bd"}, + {"Default-Features", "df"}, + }}); REQUIRE(m_pgh.has_value()); auto& pgh = **m_pgh.get(); @@ -53,13 +71,11 @@ TEST_CASE ("SourceParagraph construct maximum", "[paragraph]") TEST_CASE ("SourceParagraph two depends", "[paragraph]") { - auto m_pgh = - vcpkg::SourceControlFile::parse_control_file("", - std::vector<std::unordered_map<std::string, std::string>>{{ - {"Source", "zlib"}, - {"Version", "1.2.8"}, - {"Build-Depends", "z, openssl"}, - }}); + auto m_pgh = test_parse_control_file({{ + {"Source", "zlib"}, + {"Version", "1.2.8"}, + {"Build-Depends", "z, openssl"}, + }}); REQUIRE(m_pgh.has_value()); auto& pgh = **m_pgh.get(); @@ -70,13 +86,11 @@ TEST_CASE ("SourceParagraph two depends", "[paragraph]") TEST_CASE ("SourceParagraph three depends", "[paragraph]") { - auto m_pgh = - vcpkg::SourceControlFile::parse_control_file("", - std::vector<std::unordered_map<std::string, std::string>>{{ - {"Source", "zlib"}, - {"Version", "1.2.8"}, - {"Build-Depends", "z, openssl, xyz"}, - }}); + auto m_pgh = test_parse_control_file({{ + {"Source", "zlib"}, + {"Version", "1.2.8"}, + {"Build-Depends", "z, openssl, xyz"}, + }}); REQUIRE(m_pgh.has_value()); auto& pgh = **m_pgh.get(); @@ -88,13 +102,11 @@ TEST_CASE ("SourceParagraph three depends", "[paragraph]") TEST_CASE ("SourceParagraph construct qualified depends", "[paragraph]") { - auto m_pgh = - vcpkg::SourceControlFile::parse_control_file("", - std::vector<std::unordered_map<std::string, std::string>>{{ - {"Source", "zlib"}, - {"Version", "1.2.8"}, - {"Build-Depends", "liba (windows), libb (uwp)"}, - }}); + auto m_pgh = test_parse_control_file({{ + {"Source", "zlib"}, + {"Version", "1.2.8"}, + {"Build-Depends", "liba (windows), libb (uwp)"}, + }}); REQUIRE(m_pgh.has_value()); auto& pgh = **m_pgh.get(); @@ -111,13 +123,11 @@ TEST_CASE ("SourceParagraph construct qualified depends", "[paragraph]") TEST_CASE ("SourceParagraph default features", "[paragraph]") { - auto m_pgh = - vcpkg::SourceControlFile::parse_control_file("", - std::vector<std::unordered_map<std::string, std::string>>{{ - {"Source", "a"}, - {"Version", "1.0"}, - {"Default-Features", "a1"}, - }}); + auto m_pgh = test_parse_control_file({{ + {"Source", "a"}, + {"Version", "1.0"}, + {"Default-Features", "a1"}, + }}); REQUIRE(m_pgh.has_value()); auto& pgh = **m_pgh.get(); @@ -127,7 +137,7 @@ TEST_CASE ("SourceParagraph default features", "[paragraph]") TEST_CASE ("BinaryParagraph construct minimum", "[paragraph]") { - vcpkg::BinaryParagraph pgh({ + auto pgh = test_make_binary_paragraph({ {"Package", "zlib"}, {"Version", "1.2.8"}, {"Architecture", "x86-windows"}, @@ -144,7 +154,7 @@ TEST_CASE ("BinaryParagraph construct minimum", "[paragraph]") TEST_CASE ("BinaryParagraph construct maximum", "[paragraph]") { - vcpkg::BinaryParagraph pgh({ + auto pgh = test_make_binary_paragraph({ {"Package", "s"}, {"Version", "v"}, {"Architecture", "x86-windows"}, @@ -164,7 +174,7 @@ TEST_CASE ("BinaryParagraph construct maximum", "[paragraph]") TEST_CASE ("BinaryParagraph three depends", "[paragraph]") { - vcpkg::BinaryParagraph pgh({ + auto pgh = test_make_binary_paragraph({ {"Package", "zlib"}, {"Version", "1.2.8"}, {"Architecture", "x86-windows"}, @@ -180,7 +190,7 @@ TEST_CASE ("BinaryParagraph three depends", "[paragraph]") TEST_CASE ("BinaryParagraph abi", "[paragraph]") { - vcpkg::BinaryParagraph pgh({ + auto pgh = test_make_binary_paragraph({ {"Package", "zlib"}, {"Version", "1.2.8"}, {"Architecture", "x86-windows"}, @@ -194,7 +204,7 @@ TEST_CASE ("BinaryParagraph abi", "[paragraph]") TEST_CASE ("BinaryParagraph default features", "[paragraph]") { - vcpkg::BinaryParagraph pgh({ + auto pgh = test_make_binary_paragraph({ {"Package", "a"}, {"Version", "1.0"}, {"Architecture", "x86-windows"}, @@ -220,7 +230,7 @@ TEST_CASE ("parse paragraphs one field", "[paragraph]") auto pghs = vcpkg::Paragraphs::parse_paragraphs(str, "").value_or_exit(VCPKG_LINE_INFO); REQUIRE(pghs.size() == 1); REQUIRE(pghs[0].size() == 1); - REQUIRE(pghs[0]["f1"] == "v1"); + REQUIRE(pghs[0]["f1"].first == "v1"); } TEST_CASE ("parse paragraphs one pgh", "[paragraph]") @@ -230,8 +240,8 @@ TEST_CASE ("parse paragraphs one pgh", "[paragraph]") auto pghs = vcpkg::Paragraphs::parse_paragraphs(str, "").value_or_exit(VCPKG_LINE_INFO); REQUIRE(pghs.size() == 1); REQUIRE(pghs[0].size() == 2); - REQUIRE(pghs[0]["f1"] == "v1"); - REQUIRE(pghs[0]["f2"] == "v2"); + REQUIRE(pghs[0]["f1"].first == "v1"); + REQUIRE(pghs[0]["f2"].first == "v2"); } TEST_CASE ("parse paragraphs two pgh", "[paragraph]") @@ -245,11 +255,11 @@ TEST_CASE ("parse paragraphs two pgh", "[paragraph]") REQUIRE(pghs.size() == 2); REQUIRE(pghs[0].size() == 2); - REQUIRE(pghs[0]["f1"] == "v1"); - REQUIRE(pghs[0]["f2"] == "v2"); + REQUIRE(pghs[0]["f1"].first == "v1"); + REQUIRE(pghs[0]["f2"].first == "v2"); REQUIRE(pghs[1].size() == 2); - REQUIRE(pghs[1]["f3"] == "v3"); - REQUIRE(pghs[1]["f4"] == "v4"); + REQUIRE(pghs[1]["f3"].first == "v3"); + REQUIRE(pghs[1]["f4"].first == "v4"); } TEST_CASE ("parse paragraphs field names", "[paragraph]") @@ -286,8 +296,8 @@ TEST_CASE ("parse paragraphs empty fields", "[paragraph]") REQUIRE(pghs.size() == 1); REQUIRE(pghs[0].size() == 2); - REQUIRE(pghs[0]["f1"] == ""); - REQUIRE(pghs[0]["f2"] == ""); + REQUIRE(pghs[0]["f1"].first == ""); + REQUIRE(pghs[0]["f2"].first == ""); REQUIRE(pghs[0].size() == 2); } @@ -301,8 +311,8 @@ TEST_CASE ("parse paragraphs multiline fields", "[paragraph]") auto pghs = vcpkg::Paragraphs::parse_paragraphs(str, "").value_or_exit(VCPKG_LINE_INFO); REQUIRE(pghs.size() == 1); - REQUIRE(pghs[0]["f1"] == "simple\n f1"); - REQUIRE(pghs[0]["f2"] == "\n f2\n continue"); + REQUIRE(pghs[0]["f1"].first == "simple\n f1"); + REQUIRE(pghs[0]["f2"].first == "\n f2\n continue"); } TEST_CASE ("parse paragraphs crlfs", "[paragraph]") @@ -316,11 +326,11 @@ TEST_CASE ("parse paragraphs crlfs", "[paragraph]") REQUIRE(pghs.size() == 2); REQUIRE(pghs[0].size() == 2); - REQUIRE(pghs[0]["f1"] == "v1"); - REQUIRE(pghs[0]["f2"] == "v2"); + REQUIRE(pghs[0]["f1"].first == "v1"); + REQUIRE(pghs[0]["f2"].first == "v2"); REQUIRE(pghs[1].size() == 2); - REQUIRE(pghs[1]["f3"] == "v3"); - REQUIRE(pghs[1]["f4"] == "v4"); + REQUIRE(pghs[1]["f3"].first == "v3"); + REQUIRE(pghs[1]["f4"].first == "v4"); } TEST_CASE ("parse paragraphs comment", "[paragraph]") @@ -338,11 +348,11 @@ TEST_CASE ("parse paragraphs comment", "[paragraph]") REQUIRE(pghs.size() == 2); REQUIRE(pghs[0].size() == 2); - REQUIRE(pghs[0]["f1"] == "v1"); - REQUIRE(pghs[0]["f2"] == "v2"); + REQUIRE(pghs[0]["f1"].first == "v1"); + REQUIRE(pghs[0]["f2"].first == "v2"); REQUIRE(pghs[1].size()); - REQUIRE(pghs[1]["f3"] == "v3"); - REQUIRE(pghs[1]["f4"] == "v4"); + REQUIRE(pghs[1]["f3"].first == "v3"); + REQUIRE(pghs[1]["f4"].first == "v4"); } TEST_CASE ("parse comment before single line feed", "[paragraph]") @@ -351,12 +361,12 @@ TEST_CASE ("parse comment before single line feed", "[paragraph]") "#comment\n"; auto pghs = vcpkg::Paragraphs::parse_paragraphs(str, "").value_or_exit(VCPKG_LINE_INFO); REQUIRE(pghs[0].size() == 1); - REQUIRE(pghs[0]["f1"] == "v1"); + REQUIRE(pghs[0]["f1"].first == "v1"); } TEST_CASE ("BinaryParagraph serialize min", "[paragraph]") { - vcpkg::BinaryParagraph pgh({ + auto pgh = test_make_binary_paragraph({ {"Package", "zlib"}, {"Version", "1.2.8"}, {"Architecture", "x86-windows"}, @@ -367,16 +377,16 @@ TEST_CASE ("BinaryParagraph serialize min", "[paragraph]") REQUIRE(pghs.size() == 1); REQUIRE(pghs[0].size() == 5); - REQUIRE(pghs[0]["Package"] == "zlib"); - REQUIRE(pghs[0]["Version"] == "1.2.8"); - REQUIRE(pghs[0]["Architecture"] == "x86-windows"); - REQUIRE(pghs[0]["Multi-Arch"] == "same"); - REQUIRE(pghs[0]["Type"] == "Port"); + REQUIRE(pghs[0]["Package"].first == "zlib"); + REQUIRE(pghs[0]["Version"].first == "1.2.8"); + REQUIRE(pghs[0]["Architecture"].first == "x86-windows"); + REQUIRE(pghs[0]["Multi-Arch"].first == "same"); + REQUIRE(pghs[0]["Type"].first == "Port"); } TEST_CASE ("BinaryParagraph serialize max", "[paragraph]") { - vcpkg::BinaryParagraph pgh({ + auto pgh = test_make_binary_paragraph({ {"Package", "zlib"}, {"Version", "1.2.8"}, {"Architecture", "x86-windows"}, @@ -390,18 +400,18 @@ TEST_CASE ("BinaryParagraph serialize max", "[paragraph]") REQUIRE(pghs.size() == 1); REQUIRE(pghs[0].size() == 8); - REQUIRE(pghs[0]["Package"] == "zlib"); - REQUIRE(pghs[0]["Version"] == "1.2.8"); - REQUIRE(pghs[0]["Architecture"] == "x86-windows"); - REQUIRE(pghs[0]["Multi-Arch"] == "same"); - REQUIRE(pghs[0]["Description"] == "first line\n second line"); - REQUIRE(pghs[0]["Depends"] == "dep"); - REQUIRE(pghs[0]["Type"] == "Port"); + REQUIRE(pghs[0]["Package"].first == "zlib"); + REQUIRE(pghs[0]["Version"].first == "1.2.8"); + REQUIRE(pghs[0]["Architecture"].first == "x86-windows"); + REQUIRE(pghs[0]["Multi-Arch"].first == "same"); + REQUIRE(pghs[0]["Description"].first == "first line\n second line"); + REQUIRE(pghs[0]["Depends"].first == "dep"); + REQUIRE(pghs[0]["Type"].first == "Port"); } TEST_CASE ("BinaryParagraph serialize multiple deps", "[paragraph]") { - vcpkg::BinaryParagraph pgh({ + auto pgh = test_make_binary_paragraph({ {"Package", "zlib"}, {"Version", "1.2.8"}, {"Architecture", "x86-windows"}, @@ -412,12 +422,12 @@ TEST_CASE ("BinaryParagraph serialize multiple deps", "[paragraph]") auto pghs = vcpkg::Paragraphs::parse_paragraphs(ss, "").value_or_exit(VCPKG_LINE_INFO); REQUIRE(pghs.size() == 1); - REQUIRE(pghs[0]["Depends"] == "a, b, c"); + REQUIRE(pghs[0]["Depends"].first == "a, b, c"); } TEST_CASE ("BinaryParagraph serialize abi", "[paragraph]") { - vcpkg::BinaryParagraph pgh({ + auto pgh = test_make_binary_paragraph({ {"Package", "zlib"}, {"Version", "1.2.8"}, {"Architecture", "x86-windows"}, @@ -429,5 +439,5 @@ TEST_CASE ("BinaryParagraph serialize abi", "[paragraph]") auto pghs = vcpkg::Paragraphs::parse_paragraphs(ss, "").value_or_exit(VCPKG_LINE_INFO); REQUIRE(pghs.size() == 1); - REQUIRE(pghs[0]["Abi"] == "123abc"); + REQUIRE(pghs[0]["Abi"].first == "123abc"); } diff --git a/toolsrc/src/vcpkg-test/statusparagraphs.cpp b/toolsrc/src/vcpkg-test/statusparagraphs.cpp index c755948b5..acb8b333c 100644 --- a/toolsrc/src/vcpkg-test/statusparagraphs.cpp +++ b/toolsrc/src/vcpkg-test/statusparagraphs.cpp @@ -24,7 +24,7 @@ Status: install ok installed REQUIRE(pghs); StatusParagraphs status_db( - Util::fmap(*pghs.get(), [](RawParagraph& rpgh) { return std::make_unique<StatusParagraph>(std::move(rpgh)); })); + Util::fmap(*pghs.get(), [](Paragraph& rpgh) { return std::make_unique<StatusParagraph>(std::move(rpgh)); })); auto it = status_db.find_installed({"ffmpeg", Triplet::X64_WINDOWS}); REQUIRE(it != status_db.end()); @@ -45,7 +45,7 @@ Status: purge ok not-installed REQUIRE(pghs); StatusParagraphs status_db( - Util::fmap(*pghs.get(), [](RawParagraph& rpgh) { return std::make_unique<StatusParagraph>(std::move(rpgh)); })); + Util::fmap(*pghs.get(), [](Paragraph& rpgh) { return std::make_unique<StatusParagraph>(std::move(rpgh)); })); auto it = status_db.find_installed({"ffmpeg", Triplet::X64_WINDOWS}); REQUIRE(it == status_db.end()); @@ -74,7 +74,7 @@ Status: purge ok not-installed REQUIRE(pghs); StatusParagraphs status_db( - Util::fmap(*pghs.get(), [](RawParagraph& rpgh) { return std::make_unique<StatusParagraph>(std::move(rpgh)); })); + Util::fmap(*pghs.get(), [](Paragraph& rpgh) { return std::make_unique<StatusParagraph>(std::move(rpgh)); })); auto it = status_db.find_installed({"ffmpeg", Triplet::X64_WINDOWS}); REQUIRE(it != status_db.end()); @@ -106,7 +106,7 @@ Status: install ok installed REQUIRE(pghs); StatusParagraphs status_db( - Util::fmap(*pghs.get(), [](RawParagraph& rpgh) { return std::make_unique<StatusParagraph>(std::move(rpgh)); })); + Util::fmap(*pghs.get(), [](Paragraph& rpgh) { return std::make_unique<StatusParagraph>(std::move(rpgh)); })); // Feature "openssl" is installed and should therefore be found auto it = status_db.find_installed({{"ffmpeg", Triplet::X64_WINDOWS}, "openssl"}); diff --git a/toolsrc/src/vcpkg-test/update.cpp b/toolsrc/src/vcpkg-test/update.cpp index a362df720..5370a8421 100644 --- a/toolsrc/src/vcpkg-test/update.cpp +++ b/toolsrc/src/vcpkg-test/update.cpp @@ -20,7 +20,7 @@ TEST_CASE ("find outdated packages basic", "[update]") StatusParagraphs status_db(std::move(status_paragraphs)); std::unordered_map<std::string, SourceControlFileLocation> map; - auto scf = unwrap(SourceControlFile::parse_control_file("", Pgh{{{"Source", "a"}, {"Version", "0"}}})); + auto scf = unwrap(test_parse_control_file({{{"Source", "a"}, {"Version", "0"}}})); map.emplace("a", SourceControlFileLocation{std::move(scf), ""}); PortFileProvider::MapPortFileProvider provider(map); @@ -44,7 +44,7 @@ TEST_CASE ("find outdated packages features", "[update]") StatusParagraphs status_db(std::move(status_paragraphs)); std::unordered_map<std::string, SourceControlFileLocation> map; - auto scf = unwrap(SourceControlFile::parse_control_file("", Pgh{{{"Source", "a"}, {"Version", "0"}}})); + auto scf = unwrap(test_parse_control_file({{{"Source", "a"}, {"Version", "0"}}})); map.emplace("a", SourceControlFileLocation{std::move(scf), ""}); PortFileProvider::MapPortFileProvider provider(map); @@ -70,7 +70,7 @@ TEST_CASE ("find outdated packages features 2", "[update]") StatusParagraphs status_db(std::move(status_paragraphs)); std::unordered_map<std::string, SourceControlFileLocation> map; - auto scf = unwrap(SourceControlFile::parse_control_file("", Pgh{{{"Source", "a"}, {"Version", "0"}}})); + auto scf = unwrap(test_parse_control_file({{{"Source", "a"}, {"Version", "0"}}})); map.emplace("a", SourceControlFileLocation{std::move(scf), ""}); PortFileProvider::MapPortFileProvider provider(map); @@ -91,7 +91,7 @@ TEST_CASE ("find outdated packages none", "[update]") StatusParagraphs status_db(std::move(status_paragraphs)); std::unordered_map<std::string, SourceControlFileLocation> map; - auto scf = unwrap(SourceControlFile::parse_control_file("", Pgh{{{"Source", "a"}, {"Version", "2"}}})); + auto scf = unwrap(test_parse_control_file({{{"Source", "a"}, {"Version", "2"}}})); map.emplace("a", SourceControlFileLocation{std::move(scf), ""}); PortFileProvider::MapPortFileProvider provider(map); diff --git a/toolsrc/src/vcpkg-test/util.cpp b/toolsrc/src/vcpkg-test/util.cpp index ae02e3ab0..d754baec1 100644 --- a/toolsrc/src/vcpkg-test/util.cpp +++ b/toolsrc/src/vcpkg-test/util.cpp @@ -58,7 +58,7 @@ namespace vcpkg::Test {"Build-Depends", feature.second}, }); } - auto m_pgh = vcpkg::SourceControlFile::parse_control_file("", std::move(scf_pghs)); + auto m_pgh = test_parse_control_file(std::move(scf_pghs)); REQUIRE(m_pgh.has_value()); return std::move(*m_pgh.get()); } @@ -68,14 +68,13 @@ namespace vcpkg::Test const char* default_features, const char* triplet) { - using Pgh = std::unordered_map<std::string, std::string>; - return std::make_unique<StatusParagraph>(Pgh{{"Package", name}, - {"Version", "1"}, - {"Architecture", triplet}, - {"Multi-Arch", "same"}, - {"Depends", depends}, - {"Default-Features", default_features}, - {"Status", "install ok installed"}}); + return std::make_unique<StatusParagraph>(Parse::Paragraph{{"Package", {name, {}}}, + {"Version", {"1", {}}}, + {"Architecture", {triplet, {}}}, + {"Multi-Arch", {"same", {}}}, + {"Depends", {depends, {}}}, + {"Default-Features", {default_features, {}}}, + {"Status", {"install ok installed", {}}}}); } std::unique_ptr<StatusParagraph> make_status_feature_pgh(const char* name, @@ -83,14 +82,12 @@ namespace vcpkg::Test const char* depends, const char* triplet) { - using Pgh = std::unordered_map<std::string, std::string>; - return std::make_unique<StatusParagraph>(Pgh{{"Package", name}, - {"Version", "1"}, - {"Feature", feature}, - {"Architecture", triplet}, - {"Multi-Arch", "same"}, - {"Depends", depends}, - {"Status", "install ok installed"}}); + return std::make_unique<StatusParagraph>(Parse::Paragraph{{"Package", {name, {}}}, + {"Feature", {feature, {}}}, + {"Architecture", {triplet, {}}}, + {"Multi-Arch", {"same", {}}}, + {"Depends", {depends, {}}}, + {"Status", {"install ok installed", {}}}}); } PackageSpec PackageSpecMap::emplace(const char* name, diff --git a/toolsrc/src/vcpkg/binaryparagraph.cpp b/toolsrc/src/vcpkg/binaryparagraph.cpp index e97400150..f142c307d 100644 --- a/toolsrc/src/vcpkg/binaryparagraph.cpp +++ b/toolsrc/src/vcpkg/binaryparagraph.cpp @@ -30,7 +30,7 @@ namespace vcpkg BinaryParagraph::BinaryParagraph() = default; - BinaryParagraph::BinaryParagraph(Parse::RawParagraph fields) + BinaryParagraph::BinaryParagraph(Parse::Paragraph fields) { using namespace vcpkg::Parse; diff --git a/toolsrc/src/vcpkg/build.cpp b/toolsrc/src/vcpkg/build.cpp index 2637410b2..de787505a 100644 --- a/toolsrc/src/vcpkg/build.cpp +++ b/toolsrc/src/vcpkg/build.cpp @@ -1011,7 +1011,7 @@ namespace vcpkg::Build Commands::Version::version());
}
- static BuildInfo inner_create_buildinfo(Parse::RawParagraph pgh)
+ static BuildInfo inner_create_buildinfo(Parse::Paragraph pgh)
{
Parse::ParagraphParser parser(std::move(pgh));
@@ -1068,7 +1068,7 @@ namespace vcpkg::Build BuildInfo read_build_info(const Files::Filesystem& fs, const fs::path& filepath)
{
- const ExpectedS<Parse::RawParagraph> pghs = Paragraphs::get_single_paragraph(fs, filepath);
+ const ExpectedS<Parse::Paragraph> pghs = Paragraphs::get_single_paragraph(fs, filepath);
Checks::check_exit(
VCPKG_LINE_INFO, pghs.get() != nullptr, "Invalid BUILD_INFO file for package: %s", pghs.error());
return inner_create_buildinfo(*pghs.get());
diff --git a/toolsrc/src/vcpkg/commands.ci.cpp b/toolsrc/src/vcpkg/commands.ci.cpp index 301400b8b..fd810acf6 100644 --- a/toolsrc/src/vcpkg/commands.ci.cpp +++ b/toolsrc/src/vcpkg/commands.ci.cpp @@ -224,12 +224,10 @@ namespace vcpkg::Commands::CI }; static bool supported_for_triplet(const CMakeVars::TripletCMakeVarProvider& var_provider, - const InstallPlanAction* install_plan) { - const std::string& supports_expression = - install_plan->source_control_file_location.value_or_exit(VCPKG_LINE_INFO) - .source_control_file->core_paragraph->supports_expression; + auto&& scfl = install_plan->source_control_file_location.value_or_exit(VCPKG_LINE_INFO); + const std::string& supports_expression = scfl.source_control_file->core_paragraph->supports_expression; if (supports_expression.empty()) { return true; // default to 'supported' diff --git a/toolsrc/src/vcpkg/paragraphs.cpp b/toolsrc/src/vcpkg/paragraphs.cpp index 8f1b72172..82bc7b109 100644 --- a/toolsrc/src/vcpkg/paragraphs.cpp +++ b/toolsrc/src/vcpkg/paragraphs.cpp @@ -40,7 +40,7 @@ namespace vcpkg::Paragraphs if (fieldname.empty()) return add_error("expected fieldname"); } - void get_paragraph(RawParagraph& fields) + void get_paragraph(Paragraph& fields) { fields.clear(); std::string fieldname; @@ -59,17 +59,17 @@ namespace vcpkg::Paragraphs if (Util::Sets::contains(fields, fieldname)) return add_error("duplicate field", loc); next(); skip_tabs_spaces(); - + auto rowcol = cur_rowcol(); get_fieldvalue(fieldvalue); - fields.emplace(fieldname, fieldvalue); + fields.emplace(fieldname, std::make_pair(fieldvalue, rowcol)); } while (!is_lineend(cur())); } public: - ExpectedS<std::vector<RawParagraph>> get_paragraphs(CStringView text, CStringView origin) + ExpectedS<std::vector<Paragraph>> get_paragraphs(CStringView text, CStringView origin) { - std::vector<RawParagraph> paragraphs; + std::vector<Paragraph> paragraphs; init(text, origin); @@ -86,7 +86,7 @@ namespace vcpkg::Paragraphs } }; - static ExpectedS<RawParagraph> parse_single_paragraph(const std::string& str, const std::string& origin) + static ExpectedS<Paragraph> parse_single_paragraph(const std::string& str, const std::string& origin) { PghParser parser; auto pghs = parser.get_paragraphs(str, origin); @@ -102,7 +102,7 @@ namespace vcpkg::Paragraphs } } - ExpectedS<RawParagraph> get_single_paragraph(const Files::Filesystem& fs, const fs::path& control_path) + ExpectedS<Paragraph> get_single_paragraph(const Files::Filesystem& fs, const fs::path& control_path) { const Expected<std::string> contents = fs.read_contents(control_path); if (auto spgh = contents.get()) @@ -113,7 +113,7 @@ namespace vcpkg::Paragraphs return contents.error().message(); } - ExpectedS<std::vector<RawParagraph>> get_paragraphs(const Files::Filesystem& fs, const fs::path& control_path) + ExpectedS<std::vector<Paragraph>> get_paragraphs(const Files::Filesystem& fs, const fs::path& control_path) { const Expected<std::string> contents = fs.read_contents(control_path); if (auto spgh = contents.get()) @@ -124,7 +124,7 @@ namespace vcpkg::Paragraphs return contents.error().message(); } - ExpectedS<std::vector<RawParagraph>> parse_paragraphs(const std::string& str, const std::string& origin) + ExpectedS<std::vector<Paragraph>> parse_paragraphs(const std::string& str, const std::string& origin) { PghParser parser; return parser.get_paragraphs(str, origin); @@ -133,7 +133,7 @@ namespace vcpkg::Paragraphs ParseExpected<SourceControlFile> try_load_port(const Files::Filesystem& fs, const fs::path& path) { const auto path_to_control = path / "CONTROL"; - ExpectedS<std::vector<RawParagraph>> pghs = get_paragraphs(fs, path_to_control); + ExpectedS<std::vector<Paragraph>> pghs = get_paragraphs(fs, path_to_control); if (auto vector_pghs = pghs.get()) { return SourceControlFile::parse_control_file(path_to_control, std::move(*vector_pghs)); @@ -146,7 +146,7 @@ namespace vcpkg::Paragraphs ExpectedS<BinaryControlFile> try_load_cached_package(const VcpkgPaths& paths, const PackageSpec& spec) { - ExpectedS<std::vector<RawParagraph>> pghs = + ExpectedS<std::vector<Paragraph>> pghs = get_paragraphs(paths.get_filesystem(), paths.package_dir(spec) / "CONTROL"); if (auto p = pghs.get()) diff --git a/toolsrc/src/vcpkg/parse.cpp b/toolsrc/src/vcpkg/parse.cpp index 0bc748794..9e33c95f9 100644 --- a/toolsrc/src/vcpkg/parse.cpp +++ b/toolsrc/src/vcpkg/parse.cpp @@ -11,8 +11,28 @@ using namespace vcpkg; namespace vcpkg::Parse { + static void advance_rowcol(char ch, int& row, int& column) + { + if (ch == '\t') + column = (column + 7) / 8 * 8 + 1; // round to next 8-width tab stop + else if (ch == '\n') + { + row++; + column = 1; + } + else + { + ++column; + } + } + std::string ParseError::format() const { + int ignore_row = 1; + int spacing = 20; + for (int i = 0; i < caret_col; ++i) + advance_rowcol(line[i], ignore_row, spacing); + return Strings::concat("Error: ", origin, ":", @@ -22,14 +42,26 @@ namespace vcpkg::Parse ": ", message, "\n" - " on expression: \"", + " on expression: \"", // 9 columns line, "\"\n", - " ", - std::string(column - 1, ' '), + std::string(spacing - 1, ' '), "^\n"); } + char ParserBase::next() + { + char ch = *m_it; + // See https://www.gnu.org/prep/standards/standards.html#Errors + if (ch == '\0') + { + return '\0'; + } + else + advance_rowcol(ch, row, column); + return *++m_it; + } + void ParserBase::add_error(std::string message, const ParserBase::SourceLoc& loc) { // avoid cascading errors by only saving the first @@ -47,15 +79,19 @@ namespace vcpkg::Parse auto lineend = loc.it; while (*lineend != '\n' && *lineend != '\r' && *lineend != '\0') ++lineend; - m_err.reset( - new ParseError(m_origin.c_str(), loc.row, loc.column, {linestart, lineend}, std::move(message))); + m_err.reset(new ParseError(m_origin.c_str(), + loc.row, + loc.column, + static_cast<int>(loc.it - linestart), + {linestart, lineend}, + std::move(message))); } // Avoid error loops by skipping to the end skip_to_eof(); } - static Optional<std::string> remove_field(RawParagraph* fields, const std::string& fieldname) + static Optional<std::pair<std::string, TextRowCol>> remove_field(Paragraph* fields, const std::string& fieldname) { auto it = fields->find(fieldname); if (it == fields->end()) @@ -63,12 +99,12 @@ namespace vcpkg::Parse return nullopt; } - const std::string value = std::move(it->second); + auto value = std::move(it->second); fields->erase(it); return value; } - void ParagraphParser::required_field(const std::string& fieldname, std::string& out) + 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()) @@ -76,10 +112,24 @@ namespace vcpkg::Parse else missing_fields.push_back(fieldname); } - std::string ParagraphParser::optional_field(const std::string& fieldname) const + void ParagraphParser::optional_field(const std::string& fieldname, std::pair<std::string&, TextRowCol&> out) { - return remove_field(&fields, fieldname).value_or(""); + 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::unique_ptr<ParseControlErrorInfo> ParagraphParser::error_info(const std::string& name) const { if (!fields.empty() || !missing_fields.empty()) @@ -116,29 +166,34 @@ namespace vcpkg::Parse } while (true); } - ExpectedS<std::vector<std::string>> parse_default_features_list(const std::string& str, CStringView origin) + ExpectedS<std::vector<std::string>> parse_default_features_list(const std::string& str, + CStringView origin, + TextRowCol textrowcol) { Parse::ParserBase parser; - parser.init(str, origin); + parser.init(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, - CStringView origin) + CStringView origin, + TextRowCol textrowcol) { Parse::ParserBase parser; - parser.init(str, origin); + parser.init(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, CStringView origin) + ExpectedS<std::vector<Dependency>> parse_dependencies_list(const std::string& str, + CStringView origin, + TextRowCol textrowcol) { Parse::ParserBase parser; - parser.init(str, origin); + parser.init(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> { diff --git a/toolsrc/src/vcpkg/sourceparagraph.cpp b/toolsrc/src/vcpkg/sourceparagraph.cpp index e4d9ffc63..b5e0ebe31 100644 --- a/toolsrc/src/vcpkg/sourceparagraph.cpp +++ b/toolsrc/src/vcpkg/sourceparagraph.cpp @@ -115,8 +115,10 @@ namespace vcpkg return Type{Type::UNKNOWN}; } - static ParseExpected<SourceParagraph> parse_source_paragraph(const fs::path& path_to_control, RawParagraph&& fields) + static ParseExpected<SourceParagraph> parse_source_paragraph(const fs::path& path_to_control, Paragraph&& fields) { + auto origin = path_to_control.u8string(); + ParagraphParser parser(std::move(fields)); auto spgh = std::make_unique<SourceParagraph>(); @@ -127,23 +129,25 @@ namespace vcpkg spgh->description = parser.optional_field(SourceParagraphFields::DESCRIPTION); spgh->maintainer = parser.optional_field(SourceParagraphFields::MAINTAINER); spgh->homepage = parser.optional_field(SourceParagraphFields::HOMEPAGE); - spgh->depends = parse_dependencies_list(parser.optional_field(SourceParagraphFields::BUILD_DEPENDS)) - .value_or_exit(VCPKG_LINE_INFO); - spgh->default_features = - parse_default_features_list(parser.optional_field(SourceParagraphFields::DEFAULTFEATURES)) - .value_or_exit(VCPKG_LINE_INFO); + TextRowCol textrowcol; + std::string buf; + parser.optional_field(SourceParagraphFields::BUILD_DEPENDS, {buf, textrowcol}); + spgh->depends = parse_dependencies_list(buf, origin, textrowcol).value_or_exit(VCPKG_LINE_INFO); + buf.clear(); + parser.optional_field(SourceParagraphFields::DEFAULTFEATURES, {buf, textrowcol}); + spgh->default_features = parse_default_features_list(buf, origin, textrowcol).value_or_exit(VCPKG_LINE_INFO); spgh->supports_expression = parser.optional_field(SourceParagraphFields::SUPPORTS); spgh->type = Type::from_string(parser.optional_field(SourceParagraphFields::TYPE)); - auto err = parser.error_info(spgh->name.empty() ? path_to_control.u8string() : spgh->name); + auto err = parser.error_info(spgh->name.empty() ? origin : spgh->name); if (err) return err; else return spgh; } - static ParseExpected<FeatureParagraph> parse_feature_paragraph(const fs::path& path_to_control, - RawParagraph&& fields) + static ParseExpected<FeatureParagraph> parse_feature_paragraph(const fs::path& path_to_control, Paragraph&& fields) { + auto origin = path_to_control.u8string(); ParagraphParser parser(std::move(fields)); auto fpgh = std::make_unique<FeatureParagraph>(); @@ -151,10 +155,10 @@ namespace vcpkg parser.required_field(SourceParagraphFields::FEATURE, fpgh->name); parser.required_field(SourceParagraphFields::DESCRIPTION, fpgh->description); - fpgh->depends = parse_dependencies_list(parser.optional_field(SourceParagraphFields::BUILD_DEPENDS)) + fpgh->depends = parse_dependencies_list(parser.optional_field(SourceParagraphFields::BUILD_DEPENDS), origin) .value_or_exit(VCPKG_LINE_INFO); - auto err = parser.error_info(fpgh->name.empty() ? path_to_control.u8string() : fpgh->name); + auto err = parser.error_info(fpgh->name.empty() ? origin : fpgh->name); if (err) return err; else @@ -162,7 +166,7 @@ namespace vcpkg } ParseExpected<SourceControlFile> SourceControlFile::parse_control_file( - const fs::path& path_to_control, std::vector<Parse::RawParagraph>&& control_paragraphs) + const fs::path& path_to_control, std::vector<Parse::Paragraph>&& control_paragraphs) { if (control_paragraphs.size() == 0) { diff --git a/toolsrc/src/vcpkg/statusparagraph.cpp b/toolsrc/src/vcpkg/statusparagraph.cpp index 144d079ec..ef8715ec2 100644 --- a/toolsrc/src/vcpkg/statusparagraph.cpp +++ b/toolsrc/src/vcpkg/statusparagraph.cpp @@ -24,12 +24,12 @@ namespace vcpkg .push_back('\n'); } - StatusParagraph::StatusParagraph(Parse::RawParagraph&& fields) + StatusParagraph::StatusParagraph(Parse::Paragraph&& fields) : want(Want::ERROR_STATE), state(InstallState::ERROR_STATE) { 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); + std::string status_field = std::move(status_it->second.first); fields.erase(status_it); this->package = BinaryParagraph(std::move(fields)); diff --git a/toolsrc/src/vcpkg/userconfig.cpp b/toolsrc/src/vcpkg/userconfig.cpp index a3c019be7..69bae5bfc 100644 --- a/toolsrc/src/vcpkg/userconfig.cpp +++ b/toolsrc/src/vcpkg/userconfig.cpp @@ -51,7 +51,7 @@ namespace vcpkg { const auto& pghs = *p_pghs; - Parse::RawParagraph keys; + Parse::Paragraph keys; if (pghs.size() > 0) keys = pghs[0]; for (size_t x = 1; x < pghs.size(); ++x) @@ -60,10 +60,10 @@ namespace vcpkg keys.insert(p); } - ret.user_id = keys["User-Id"]; - ret.user_time = keys["User-Since"]; - ret.user_mac = keys["Mac-Hash"]; - ret.last_completed_survey = keys["Survey-Completed"]; + ret.user_id = keys["User-Id"].first; + ret.user_time = keys["User-Since"].first; + ret.user_mac = keys["Mac-Hash"].first; + ret.last_completed_survey = keys["Survey-Completed"].first; } } catch (...) |
