AK: Use canonicalized_path in LexicalPath::relative_path

This avoids construction of LexicalPath objects.
This commit is contained in:
Max Wipfli 2021-06-29 20:59:38 +02:00 committed by Andreas Kling
parent 36c3962670
commit fb8bbdabb7
2 changed files with 24 additions and 11 deletions

View file

@ -121,21 +121,34 @@ String LexicalPath::canonicalized_path(String path)
return builder.to_string();
}
String LexicalPath::relative_path(String absolute_path, String const& prefix)
String LexicalPath::relative_path(StringView const& a_path, StringView const& a_prefix)
{
if (!LexicalPath { absolute_path }.is_absolute() || !LexicalPath { prefix }.is_absolute())
if (!a_path.starts_with('/') || !a_prefix.starts_with('/')) {
// FIXME: This should probably VERIFY or return an Optional<String>.
return {};
}
if (!absolute_path.starts_with(prefix))
return absolute_path;
if (a_path == a_prefix)
return ".";
size_t prefix_length = LexicalPath { prefix }.string().length();
if (prefix != "/")
prefix_length++;
if (prefix_length >= absolute_path.length())
return {};
// NOTE: Strip optional trailing slashes, except if the full path is only "/".
auto path = canonicalized_path(a_path);
auto prefix = canonicalized_path(a_prefix);
return absolute_path.substring(prefix_length);
if (path == prefix)
return ".";
// NOTE: Handle this special case first.
if (prefix == "/"sv)
return path.substring_view(1);
// NOTE: This means the prefix is a direct child of the path.
if (path.starts_with(prefix) && path[prefix.length()] == '/') {
return path.substring_view(prefix.length() + 1);
}
// FIXME: It's still possible to generate a relative path in this case, it just needs some "..".
return path;
}
LexicalPath LexicalPath::append(StringView const& value) const

View file

@ -33,7 +33,7 @@ public:
[[nodiscard]] LexicalPath parent() const;
[[nodiscard]] static String canonicalized_path(String);
[[nodiscard]] static String relative_path(String absolute_path, String const& prefix);
[[nodiscard]] static String relative_path(StringView const& absolute_path, StringView const& prefix);
template<typename... S>
[[nodiscard]] static LexicalPath join(String const& first, S&&... rest)