Skip to content

Commit

Permalink
Use weakly_canonical to handle non-existant paths.
Browse files Browse the repository at this point in the history
- Fix `~` substitution.
- Add more tests for to_real_path.

Signed-off-by: Tin Švagelj <tin.svagelj@live.com>
  • Loading branch information
Caellian committed Nov 15, 2024
1 parent 150c5dd commit 3915c89
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 3 deletions.
17 changes: 15 additions & 2 deletions src/common.cc
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
#include <cctype>
#include <cerrno>
#include <ctime>
#include <filesystem>
#include <string>
#include <vector>

Expand Down Expand Up @@ -140,8 +141,20 @@ double get_time() {
/// - `$HOME/a/b/../c/../../conky` -> `/home/conky_user/conky`
std::filesystem::path to_real_path(const std::filesystem::path &source) {
try {
std::string expanded = variable_substitute(source.string());
return std::filesystem::canonical(expanded);
std::string input;
if (source.string().compare(0, 1, "~") == 0) {
const char *home = std::getenv("HOME");
if (home) {
input = std::string(home) + source.string().substr(1);
} else {
input = source.string(); // Fallback if HOME is not set
}
} else {
input = source.string();
}
std::string expanded = variable_substitute(input);
std::filesystem::path absolute = std::filesystem::absolute(expanded);
return std::filesystem::weakly_canonical(absolute);
} catch (const std::filesystem::filesystem_error &e) {
// file not found or permission issues
NORM_ERR("can't canonicalize path: %s", source.c_str());
Expand Down
8 changes: 7 additions & 1 deletion tests/test-common.cc
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,13 @@ std::string get_invalid_environment_variable_name() {
return variable_name;
}

TEST_CASE("to_real_path becomes homedir", "[to_real_path]") {
TEST_CASE("to_real_path simplifies complex paths", "[to_real_path]") {
REQUIRE(to_real_path("/a/b/c/../d/../../e") == "/a/e");
}
TEST_CASE("to_real_path resolves variables", "[to_real_path]") {
REQUIRE(to_real_path("$HOME/test") == std::string(getenv("HOME")) + "/test");
}
TEST_CASE("to_real_path resolves `~` symbol", "[to_real_path]") {
REQUIRE(to_real_path("~/test") == std::string(getenv("HOME")) + "/test");
}

Expand Down

0 comments on commit 3915c89

Please sign in to comment.