Skip to content

Commit

Permalink
AK: Use canonicalized_path in LexicalPath::relative_path
Browse files Browse the repository at this point in the history
This avoids construction of LexicalPath objects.
  • Loading branch information
MaxWipfli authored and awesomekling committed Jun 30, 2021
1 parent 36c3962 commit fb8bbda
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 11 deletions.
33 changes: 23 additions & 10 deletions AK/LexicalPath.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 (a_path == a_prefix)
return ".";

if (!absolute_path.starts_with(prefix))
return absolute_path;
// NOTE: Strip optional trailing slashes, except if the full path is only "/".
auto path = canonicalized_path(a_path);
auto prefix = canonicalized_path(a_prefix);

size_t prefix_length = LexicalPath { prefix }.string().length();
if (prefix != "/")
prefix_length++;
if (prefix_length >= absolute_path.length())
return {};
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);
}

return absolute_path.substring(prefix_length);
// 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
Expand Down
2 changes: 1 addition & 1 deletion AK/LexicalPath.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ class LexicalPath {
[[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)
Expand Down

0 comments on commit fb8bbda

Please sign in to comment.