Skip to content

Commit

Permalink
Path: throw from getAbsolutePath() if the given path does not exist
Browse files Browse the repository at this point in the history
  • Loading branch information
firewave committed Nov 14, 2024
1 parent eb4ec20 commit fb1ddd7
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 2 deletions.
10 changes: 9 additions & 1 deletion lib/path.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -371,11 +371,13 @@ std::string Path::getAbsoluteFilePath(const std::string& filePath)
#elif defined(__linux__) || defined(__sun) || defined(__hpux) || defined(__GNUC__) || defined(__CPPCHECK__)
// simplify the path since any non-existent part has to exist even if discarded by ".."
std::string spath = Path::simplifyPath(filePath);
// TODO: assert if path exists?
char * absolute = realpath(spath.c_str(), nullptr);
if (absolute)
absolute_path = absolute;
free(absolute);
// only throw on realpath() fialure to resolve a path when the given one was non-existent
if (!spath.empty() && absolute_path.empty() && !exists(spath))
throw std::runtime_error("path '" + filePath + "' does not exist");
#else
#error Platform absolute path function needed
#endif
Expand Down Expand Up @@ -419,6 +421,12 @@ bool Path::isDirectory(const std::string &path)
return file_type(path) == S_IFDIR;
}

bool Path::exists(const std::string &path)
{
const auto type = file_type(path);
return type == S_IFREG || type == S_IFDIR;
}

std::string Path::join(const std::string& path1, const std::string& path2) {
if (path1.empty() || path2.empty())
return path1 + path2;
Expand Down
7 changes: 7 additions & 0 deletions lib/path.h
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,13 @@ class CPPCHECKLIB Path {
*/
static bool isDirectory(const std::string &path);

/**
* @brief Checks if a given path exists (i.e. is a file or directory)
* @param path Path to be checked
* @return true if given path exists
*/
static bool exists(const std::string &path);

/**
* join 2 paths with '/' separators
*/
Expand Down
15 changes: 14 additions & 1 deletion test/testpath.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ class TestPath : public TestFixture {
TEST_CASE(is_header);
TEST_CASE(simplifyPath);
TEST_CASE(getAbsolutePath);
TEST_CASE(exists);
}

void removeQuotationMarks() const {
Expand Down Expand Up @@ -476,7 +477,7 @@ class TestPath : public TestFixture {

#ifndef _WIN32
// the underlying realpath() call only returns something if the path actually exists
ASSERT_EQUALS("", Path::getAbsoluteFilePath("testabspath2.txt"));
ASSERT_THROW_EQUALS_2(Path::getAbsoluteFilePath("testabspath2.txt"), std::runtime_error, "path 'testabspath2.txt' does not exist");
#else
ASSERT_EQUALS(Path::toNativeSeparators(Path::join(cwd, "testabspath2.txt")), Path::getAbsoluteFilePath("testabspath2.txt"));
#endif
Expand Down Expand Up @@ -521,6 +522,18 @@ class TestPath : public TestFixture {
// TODO: test UNC paths
// TODO: test with symlinks
}

void exists() const {
ScopedFile file("testpath.txt", "", "testpath");
ScopedFile file2("testpath2.txt", "");
ASSERT_EQUALS(true, Path::exists("testpath"));
ASSERT_EQUALS(true, Path::exists("testpath/testpath.txt"));
ASSERT_EQUALS(true, Path::exists("testpath2.txt"));

ASSERT_EQUALS(false, Path::exists("testpath2"));
ASSERT_EQUALS(false, Path::exists("testpath/testpath2.txt"));
ASSERT_EQUALS(false, Path::exists("testpath.txt"));
}
};

REGISTER_TEST(TestPath)

0 comments on commit fb1ddd7

Please sign in to comment.