aboutsummaryrefslogtreecommitdiff
path: root/toolsrc/src
diff options
context:
space:
mode:
authorRobert Schumacher <roschuma@microsoft.com>2020-02-09 14:50:26 -0800
committerGitHub <noreply@github.com>2020-02-09 14:50:26 -0800
commita33044c18637d3df6de93128d33dae1fb5ba575c (patch)
tree273838dd27daed933e63bc7d29a28b569557755f /toolsrc/src
parent039098c9546195a50e45c41e37d7e2b9168b4245 (diff)
downloadvcpkg-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.cpp184
-rw-r--r--toolsrc/src/vcpkg-test/statusparagraphs.cpp8
-rw-r--r--toolsrc/src/vcpkg-test/update.cpp8
-rw-r--r--toolsrc/src/vcpkg-test/util.cpp31
-rw-r--r--toolsrc/src/vcpkg/binaryparagraph.cpp2
-rw-r--r--toolsrc/src/vcpkg/build.cpp4
-rw-r--r--toolsrc/src/vcpkg/commands.ci.cpp6
-rw-r--r--toolsrc/src/vcpkg/paragraphs.cpp22
-rw-r--r--toolsrc/src/vcpkg/parse.cpp87
-rw-r--r--toolsrc/src/vcpkg/sourceparagraph.cpp28
-rw-r--r--toolsrc/src/vcpkg/statusparagraph.cpp4
-rw-r--r--toolsrc/src/vcpkg/userconfig.cpp10
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 (...)