[Base] Remove multiple trailing separators in path

This commit is contained in:
Gliniak 2021-06-23 23:21:01 +02:00 committed by Rick Gibbed
parent 498c662c61
commit dcffc1a4d5

View file

@ -582,43 +582,40 @@ std::string find_name_from_path(const std::string_view path,
auto it = end; auto it = end;
--it; --it;
// path is padded with separator // skip trailing separators at the end of the path
size_t padding = 0; while (*it == uint32_t(separator)) {
if (*it == uint32_t(separator)) {
if (it == begin) { if (it == begin) {
// path is all separators, name is empty
return std::string(); return std::string();
} }
--it; --it;
padding = 1;
} }
// path is just separator // update end so it is before any trailing separators
if (it == begin) { end = std::next(it);
return std::string();
}
// search for separator // skip non-separators
while (it != begin) { while (*it != uint32_t(separator)) {
if (*it == uint32_t(separator)) { if (it == begin) {
break; break;
} }
--it; --it;
} }
// no separator -- copy entire string (except trailing separator) // if the iterator is on a separator, advance
if (it == begin) { if (*it == uint32_t(separator)) {
return std::string(path.substr(0, path.size() - padding)); ++it;
} }
auto length = byte_length(std::next(it), end); auto offset = byte_length(begin, it);
auto offset = path.length() - length; auto length = byte_length(it, end);
return std::string(path.substr(offset, length - padding)); return std::string(path.substr(offset, length));
} }
std::string find_base_name_from_path(const std::string_view path, std::string find_base_name_from_path(const std::string_view path,
char32_t separator) { char32_t separator) {
auto name = find_name_from_path(path, separator); auto name = find_name_from_path(path, separator);
if (!name.size()) { if (!name.length()) {
return std::string(); return std::string();
} }
@ -653,28 +650,34 @@ std::string find_base_path(const std::string_view path, char32_t separator) {
auto it = end; auto it = end;
--it; --it;
// skip trailing separator // skip trailing separators at the end of the path
if (*it == uint32_t(separator)) { while (*it == uint32_t(separator)) {
if (it == begin) { if (it == begin) {
return std::string(); return std::string();
} }
--it; --it;
} }
while (it != begin) { // skip non-separators
if (*it == uint32_t(separator)) { while (*it != uint32_t(separator)) {
break; if (it == begin) {
// there are no separators, base path is empty
return std::string();
} }
--it; --it;
} }
if (it == begin) { // skip trailing separators at the end of the base path
return std::string(); while (*it == uint32_t(separator)) {
if (it == begin) {
// base path is all separators, base path is empty
return std::string();
}
--it;
} }
auto length = byte_length(it, end); auto length = byte_length(begin, std::next(it));
auto offset = path.length() - length; return std::string(path.substr(0, length));
return std::string(path.substr(0, offset));
} }
std::string canonicalize_path(const std::string_view path, char32_t separator) { std::string canonicalize_path(const std::string_view path, char32_t separator) {