AK: Create relative path even if prefix is not an ancestor of the path

This commit is contained in:
Poseydon42 2022-12-11 23:33:34 +00:00 committed by Linus Groh
parent ac40090583
commit bdd7531bf5
Notes: sideshowbarker 2024-07-17 20:19:08 +09:00
2 changed files with 22 additions and 3 deletions

View file

@ -171,8 +171,25 @@ DeprecatedString LexicalPath::relative_path(StringView a_path, StringView a_pref
return path.substring_view(prefix.length() + 1); return path.substring_view(prefix.length() + 1);
} }
// FIXME: It's still possible to generate a relative path in this case, it just needs some "..". auto path_parts = path.split_view('/');
return path; auto prefix_parts = prefix.split_view('/');
size_t index_of_first_part_that_differs = 0;
for (; index_of_first_part_that_differs < path_parts.size() && index_of_first_part_that_differs < prefix_parts.size(); index_of_first_part_that_differs++) {
if (path_parts[index_of_first_part_that_differs] != prefix_parts[index_of_first_part_that_differs])
break;
}
StringBuilder builder;
for (size_t part_index = index_of_first_part_that_differs; part_index < prefix_parts.size(); part_index++) {
builder.append("../"sv);
}
for (size_t part_index = index_of_first_part_that_differs; part_index < path_parts.size(); part_index++) {
builder.append(path_parts[part_index]);
if (part_index != path_parts.size() - 1) // We don't need a slash after the file name or the name of the last directory
builder.append('/');
}
return builder.to_deprecated_string();
} }
LexicalPath LexicalPath::append(StringView value) const LexicalPath LexicalPath::append(StringView value) const

View file

@ -15,10 +15,12 @@ TEST_CASE(relative_path)
EXPECT_EQ(LexicalPath::relative_path("/tmp/abc.txt"sv, "/tmp"sv), "abc.txt"sv); EXPECT_EQ(LexicalPath::relative_path("/tmp/abc.txt"sv, "/tmp"sv), "abc.txt"sv);
EXPECT_EQ(LexicalPath::relative_path("/tmp/abc.txt"sv, "/tmp/"sv), "abc.txt"sv); EXPECT_EQ(LexicalPath::relative_path("/tmp/abc.txt"sv, "/tmp/"sv), "abc.txt"sv);
EXPECT_EQ(LexicalPath::relative_path("/tmp/abc.txt"sv, "/"sv), "tmp/abc.txt"sv); EXPECT_EQ(LexicalPath::relative_path("/tmp/abc.txt"sv, "/"sv), "tmp/abc.txt"sv);
EXPECT_EQ(LexicalPath::relative_path("/tmp/abc.txt"sv, "/usr"sv), "/tmp/abc.txt"sv); EXPECT_EQ(LexicalPath::relative_path("/tmp/abc.txt"sv, "/usr"sv), "../tmp/abc.txt"sv);
EXPECT_EQ(LexicalPath::relative_path("/tmp/foo.txt"sv, "tmp"sv), ""sv); EXPECT_EQ(LexicalPath::relative_path("/tmp/foo.txt"sv, "tmp"sv), ""sv);
EXPECT_EQ(LexicalPath::relative_path("tmp/foo.txt"sv, "/tmp"sv), ""sv); EXPECT_EQ(LexicalPath::relative_path("tmp/foo.txt"sv, "/tmp"sv), ""sv);
EXPECT_EQ(LexicalPath::relative_path("/tmp/foo/bar/baz.txt"sv, "/tmp/bar/foo/"sv), "../../foo/bar/baz.txt"sv);
} }
TEST_CASE(regular_absolute_path) TEST_CASE(regular_absolute_path)