++str_iter; | ++str_iter; | ||||
} | } | ||||
auto name = trim(std::string_view(str_begin, str_iter - str_begin)); | |||||
auto version_str = trim(std::string_view(str_iter, str_end - str_iter)); | |||||
auto name = trim_view(std::string_view(str_begin, str_iter - str_begin)); | |||||
auto version_str = trim_view(std::string_view(str_iter, str_end - str_iter)); | |||||
semver::version version; | semver::version version; | ||||
try { | try { | ||||
return std::tuple(sd.manifest.name, sd.manifest.version.to_string()); | return std::tuple(sd.manifest.name, sd.manifest.version.to_string()); | ||||
} | } | ||||
auto sdist_compare = [](const sdist& lhs, const sdist& rhs) { | |||||
return tie_sdist(lhs) < tie_sdist(rhs); | |||||
}; | |||||
auto sdist_compare | |||||
= [](const sdist& lhs, const sdist& rhs) { return tie_sdist(lhs) < tie_sdist(rhs); }; | |||||
void detail::sort_sdists(std::vector<sdist>& sd) { std::sort(sd.begin(), sd.end(), sdist_compare); } | void detail::sort_sdists(std::vector<sdist>& sd) { std::sort(sd.begin(), sd.end(), sdist_compare); } | ||||
namespace { | namespace { | ||||
const sdist* get_sdist(const std::vector<sdist>& sorted_sds, std::string_view name, std::string_view version) { | |||||
auto found = std::partition_point(sorted_sds.begin(), sorted_sds.end(), [&](const auto& candidate) { | |||||
return tie_sdist(candidate) < std::tie(name, version); | |||||
}); | |||||
const sdist* | |||||
get_sdist(const std::vector<sdist>& sorted_sds, std::string_view name, std::string_view version) { | |||||
auto found | |||||
= std::partition_point(sorted_sds.begin(), sorted_sds.end(), [&](const auto& candidate) { | |||||
return tie_sdist(candidate) < std::tie(name, version); | |||||
}); | |||||
if (found->manifest.name == name && found->manifest.version.to_string() == version) { | if (found->manifest.name == name && found->manifest.version.to_string() == version) { | ||||
return &*found; | return &*found; | ||||
} | } | ||||
return nullptr; | return nullptr; | ||||
} | } | ||||
} | |||||
} // namespace | |||||
void detail::do_find_deps(const std::vector<sdist>& sdists, | void detail::do_find_deps(const std::vector<sdist>& sdists, | ||||
const dependency& dep, | const dependency& dep, |
inline std::string_view sview(std::string_view::const_iterator beg, | inline std::string_view sview(std::string_view::const_iterator beg, | ||||
std::string_view::const_iterator end) { | std::string_view::const_iterator end) { | ||||
if (beg == end) { | |||||
return ""; | |||||
} | |||||
return std::string_view(&*beg, static_cast<std::size_t>(std::distance(beg, end))); | return std::string_view(&*beg, static_cast<std::size_t>(std::distance(beg, end))); | ||||
} | } | ||||
inline std::string_view trim(std::string_view s) { | |||||
inline std::string_view trim_view(std::string_view s) { | |||||
auto iter = s.begin(); | auto iter = s.begin(); | ||||
auto end = s.end(); | auto end = s.end(); | ||||
while (iter != end && std::isspace(*iter)) { | while (iter != end && std::isspace(*iter)) { | ||||
return sview(iter, new_end); | return sview(iter, new_end); | ||||
} | } | ||||
inline std::string_view trim(const char* str) { return trim(std::string_view(str)); } | |||||
inline std::string trim(std::string&& s) { return std::string(trim(s)); } | |||||
inline bool ends_with(std::string_view s, std::string_view key) { | inline bool ends_with(std::string_view s, std::string_view key) { | ||||
auto found = s.rfind(key); | auto found = s.rfind(key); | ||||
return found != s.npos && found == s.size() - key.size(); | return found != s.npos && found == s.size() - key.size(); |
} | } | ||||
void test_trim() { | void test_trim() { | ||||
CHECK(trim("foo") == "foo"); | |||||
CHECK(trim("foo ") == "foo"); | |||||
CHECK(trim(" ").size() == 0); | |||||
CHECK(trim_view("foo") == "foo"); | |||||
CHECK(trim_view("foo ") == "foo"); | |||||
CHECK(trim_view(" ").size() == 0); | |||||
} | } | ||||
void test_contains() { | void test_contains() { |
for (const auto& pkg_line : package_lines) { | for (const auto& pkg_line : package_lines) { | ||||
auto items = dds::split(pkg_line, ";"); | auto items = dds::split(pkg_line, ";"); | ||||
std::transform(items.begin(), items.end(), items.begin(), [](auto s) { return trim(s); }); | |||||
std::transform(items.begin(), items.end(), items.begin(), [](auto s) { | |||||
return std::string(trim_view(s)); | |||||
}); | |||||
if (items.size() != 2) { | if (items.size() != 2) { | ||||
throw std::runtime_error( | throw std::runtime_error( | ||||
fmt::format("Invalid 'Package' field in index file ({}): 'Package: {}'", | fmt::format("Invalid 'Package' field in index file ({}): 'Package: {}'", |
namespace { | namespace { | ||||
void parse_line(std::vector<pair>& pairs, const std::string_view whole_line) { | void parse_line(std::vector<pair>& pairs, const std::string_view whole_line) { | ||||
const auto line = trim(whole_line); | |||||
const auto line = trim_view(whole_line); | |||||
if (line.empty() || line[0] == '#') { | if (line.empty() || line[0] == '#') { | ||||
return; | return; | ||||
} | } | ||||
// `iter` now points to the space between the key and value | // `iter` now points to the space between the key and value | ||||
auto key = sview(begin, iter - 1); // -1 to trim the colon in the key | auto key = sview(begin, iter - 1); // -1 to trim the colon in the key | ||||
auto value = sview(iter, end); | auto value = sview(iter, end); | ||||
key = trim(key); | |||||
value = trim(value); | |||||
key = trim_view(key); | |||||
value = trim_view(value); | |||||
pairs.emplace_back(key, value); | pairs.emplace_back(key, value); | ||||
} | } | ||||