Skip to content

Commit

Permalink
Fix filesystem::separator, parentPath and basename behavior (#308)
Browse files Browse the repository at this point in the history
* Separator with an emptry string argument should return the preferred
separator for that platform
* Basename should return basename in the case with multiple trailing
slashes

Signed-off-by: Michael Carroll <michael@openrobotics.org>
Signed-off-by: Louise Poubel <louise@openrobotics.org>

Co-authored-by: Louise Poubel <louise@openrobotics.org>
  • Loading branch information
mjcarroll and chapulina authored Mar 5, 2022
1 parent ce7cb4a commit b960986
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 16 deletions.
33 changes: 18 additions & 15 deletions src/Filesystem.cc
Original file line number Diff line number Diff line change
Expand Up @@ -99,8 +99,7 @@ bool ignition::common::createDirectories(const std::string &_path)
/////////////////////////////////////////////////
std::string const ignition::common::separator(std::string const &_s)
{
fs::path path(_s);
return (_s / fs::path("")).string();
return _s + std::string{fs::path::preferred_separator};
}

/////////////////////////////////////////////////
Expand Down Expand Up @@ -144,6 +143,11 @@ std::string ignition::common::joinPaths(
fs::path p1{_path1};
fs::path p2{_path2};

if (p1.empty())
{
p1 = ignition::common::separator("");
}

bool is_url = false;

if (_path1.find("://") == std::string::npos)
Expand Down Expand Up @@ -202,24 +206,23 @@ bool ignition::common::chdir(const std::string &_dir)
std::string ignition::common::basename(const std::string &_path)
{
fs::path p(_path);
// Maintain compatibility with ign-common
if (*_path.rbegin() == fs::path::preferred_separator)
p = fs::path(_path.substr(0, _path.size()-1));
return p.filename().string();
p /= "FOO.TXT";
p = p.lexically_normal();
p = p.parent_path();
return p.filename().string().empty() ?
std::string{fs::path::preferred_separator} : p.filename().string();
}

/////////////////////////////////////////////////
std::string ignition::common::parentPath(const std::string &_path)
{
fs::path p(_path);
// Maintain compatibility with ign-common
if (*_path.rbegin() == fs::path::preferred_separator)
p = fs::path(_path.substr(0, _path.size()-1));

if (!p.has_parent_path())
return _path;

return p.parent_path().string();
std::string result;
size_t last_sep = _path.find_last_of(separator(""));
// If slash is the last character, find its parent directory
if (last_sep == _path.length() - 1)
last_sep = _path.substr(0, last_sep).find_last_of(separator(""));
result = _path.substr(0, last_sep);
return result;
}

/////////////////////////////////////////////////
Expand Down
45 changes: 44 additions & 1 deletion src/Filesystem_TEST.cc
Original file line number Diff line number Diff line change
Expand Up @@ -413,38 +413,71 @@ TEST_F(FilesystemTest, IGN_UTILS_TEST_DISABLED_ON_WIN32(cwd_error))
}

/////////////////////////////////////////////////
TEST_F(FilesystemTest, basename)
TEST_F(FilesystemTest, decomposition)
{
std::string absolute = joinPaths("", "home", "bob", "foo");
EXPECT_EQ(basename(absolute), "foo");
#ifndef _WIN32
EXPECT_EQ(parentPath(absolute), "/home/bob");
#else
EXPECT_EQ(parentPath(absolute), "\\home\\bob");
#endif

std::string relative = joinPaths("baz", "foobar");
EXPECT_EQ(basename(relative), "foobar");
EXPECT_EQ(parentPath(relative), "baz");

std::string bname = "bzzz";
EXPECT_EQ(basename(bname), "bzzz");
EXPECT_EQ(parentPath(bname), "bzzz");

std::string nobase = joinPaths("baz", "");
EXPECT_EQ(basename(nobase), "baz");
#ifndef _WIN32
EXPECT_EQ(parentPath(nobase), "baz/");
#else
EXPECT_EQ(parentPath(nobase), "baz\\");
#endif

std::string multiple_slash = separator("baz") + separator("") + separator("")
+ separator("");
EXPECT_EQ(basename(multiple_slash), "baz");
#ifndef _WIN32
EXPECT_EQ(parentPath(multiple_slash), "baz//");
#else
EXPECT_EQ(parentPath(multiple_slash), "baz\\\\");
#endif

std::string multiple_slash_middle = separator("") + separator("home")
+ separator("") + separator("") + separator("bob") + separator("foo");
EXPECT_EQ(basename(multiple_slash_middle), "foo");
#ifndef _WIN32
EXPECT_EQ(parentPath(multiple_slash_middle), "/home///bob");
#else
EXPECT_EQ(parentPath(multiple_slash_middle), "\\home\\\\\\bob");
#endif

std::string multiple_slash_start = separator("") + separator("")
+ separator("") + separator("home") + separator("bob") + separator("foo");
EXPECT_EQ(basename(multiple_slash_start), "foo");
#ifndef _WIN32
EXPECT_EQ(parentPath(multiple_slash_start), "///home/bob");
#else
EXPECT_EQ(parentPath(multiple_slash_start), "\\\\\\home\\bob");
#endif

std::string slash_only = separator("") + separator("");
EXPECT_EQ(basename(slash_only), separator(""));
EXPECT_EQ(parentPath(slash_only), "");

std::string multiple_slash_only = separator("") + separator("")
+ separator("") + separator("");
EXPECT_EQ(basename(multiple_slash_only), separator(""));
#ifndef _WIN32
EXPECT_EQ(parentPath(multiple_slash_only), "//");
#else
EXPECT_EQ(parentPath(multiple_slash_only), "\\\\");
#endif
}

/////////////////////////////////////////////////
Expand Down Expand Up @@ -611,6 +644,16 @@ TEST_F(FilesystemTest, uniquePaths)
EXPECT_TRUE(removeDirectory(dirExistingRt)) << dirExistingRt;
}

/////////////////////////////////////////////////
TEST_F(FilesystemTest, separator)
{
#ifndef _WIN32
EXPECT_EQ("/", ignition::common::separator(""));
#else
EXPECT_EQ("\\", ignition::common::separator(""));
#endif
}

/////////////////////////////////////////////////
/// Main
int main(int argc, char **argv)
Expand Down

0 comments on commit b960986

Please sign in to comment.