Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion lib/path.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -449,9 +449,13 @@ bool Path::exists(const std::string &path, bool* isdir)
return type == S_IFREG;
}

std::string Path::join(const std::string& path1, const std::string& path2) {
std::string Path::join(std::string path1, std::string path2)
{
path1 = fromNativeSeparators(std::move(path1));
path2 = fromNativeSeparators(std::move(path2));
if (path1.empty() || path2.empty())
return path1 + path2;
// this matches the behavior of std::filesystem::path::operator/=() and os.path.join()
if (path2.front() == '/')
return path2;
return ((path1.back() == '/') ? path1 : (path1 + "/")) + path2;
Expand Down
6 changes: 4 additions & 2 deletions lib/path.h
Original file line number Diff line number Diff line change
Expand Up @@ -201,9 +201,11 @@ class CPPCHECKLIB Path {
static bool exists(const std::string &path, bool* isdir = nullptr);

/**
* join 2 paths with '/' separators
* @brief join 2 paths with '/' separators
* if path2 is an absolute path path1 will be dismissed.
* @return the joined path with normalized slashes
*/
static std::string join(const std::string& path1, const std::string& path2);
static std::string join(std::string path1, std::string path2);
};

/// @}
Expand Down
29 changes: 27 additions & 2 deletions test/testpath.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -172,11 +172,36 @@ class TestPath : public TestFixture {
}

void join() const {
ASSERT_EQUALS("", Path::join("", ""));
ASSERT_EQUALS("b", Path::join("", "b"));
ASSERT_EQUALS("/b", Path::join("", "/b"));
ASSERT_EQUALS("/b", Path::join("", "\\b"));

ASSERT_EQUALS("a", Path::join("a", ""));
ASSERT_EQUALS("a", Path::join("", "a"));
ASSERT_EQUALS("a/b", Path::join("a", "b"));
ASSERT_EQUALS("a/b", Path::join("a/", "b"));
ASSERT_EQUALS("/b", Path::join("a", "/b"));
ASSERT_EQUALS("/b", Path::join("a", "\\b"));

ASSERT_EQUALS("a/", Path::join("a/", ""));
ASSERT_EQUALS("a/b", Path::join("a/", "b"));
ASSERT_EQUALS("/b", Path::join("a/", "/b"));
ASSERT_EQUALS("/b", Path::join("a/", "\\b"));

ASSERT_EQUALS("a/", Path::join("a\\", ""));
ASSERT_EQUALS("a/b", Path::join("a\\", "b"));
ASSERT_EQUALS("/b", Path::join("a\\", "/b"));
ASSERT_EQUALS("/b", Path::join("a\\", "\\b"));

// TODO: how to absolute Windows path in path2?
//ASSERT_EQUALS("", Path::join("a", "s:/b"));

//ASSERT_EQUALS("", Path::join("S:\\a", "S:/b"));
//ASSERT_EQUALS("", Path::join("S:\\a", "S:\\b"));
//ASSERT_EQUALS("", Path::join("S:\\a", "/b"));

//ASSERT_EQUALS("", Path::join("S:/a", "S:/b"));
//ASSERT_EQUALS("", Path::join("S:/a", "S:\\b"));
//ASSERT_EQUALS("", Path::join("S:/a", "/b"));
}

void isDirectory() const {
Expand Down