From acd1423a48f7360bbd014b6cd594914e64355861 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Sverre=20Lien=20Sell=C3=A6g?= Date: Wed, 30 Sep 2020 15:31:05 +0200 Subject: [PATCH] add getters for xdg directories --- src/filesystem.cpp | 70 +++++++++++++++++++++++++++++++++++++++ src/filesystem.hpp | 16 +++++++++ tests/filesystem_test.cpp | 18 ++++++++++ 3 files changed, 104 insertions(+) diff --git a/src/filesystem.cpp b/src/filesystem.cpp index 9a6f07d..9aef6d4 100644 --- a/src/filesystem.cpp +++ b/src/filesystem.cpp @@ -99,6 +99,76 @@ boost::filesystem::path filesystem::get_home_path() noexcept { return boost::filesystem::path(); } +bool filesystem::create_missing_path(const boost::filesystem::path &path) noexcept { + boost::system::error_code ec; + if(!boost::filesystem::exists(path, ec)) { + if(!boost::filesystem::create_directories(path, ec)) { + return (!ec); + } + } + return false; +} + +boost::filesystem::path filesystem::get_environment_path(const char *variable) noexcept { + try { + auto ptr = std::getenv(variable); + if(ptr) { + return boost::filesystem::path(ptr); + } + } + catch(...) { + } + return boost::filesystem::path(); +} + +const boost::filesystem::path &filesystem::get_data_path() noexcept { + static boost::filesystem::path data_path; + if(!data_path.empty()) + return data_path; + + const auto env_path = get_environment_path("XDG_DATA_HOME"); + + if(env_path.empty()) { + data_path = get_home_path() / ".local" / "share"; + } + + create_missing_path(data_path); + + return data_path; +} + +const boost::filesystem::path &filesystem::get_config_path() noexcept { + static boost::filesystem::path config_path; + if(!config_path.empty()) + return config_path; + + const auto env_path = get_environment_path("XDG_CONFIG_HOME"); + + if(env_path.empty()) { + config_path = get_home_path() / ".config"; + } + + create_missing_path(config_path); + + return config_path; +} + +const boost::filesystem::path &filesystem::get_cache_path() noexcept { + static boost::filesystem::path cache_path; + if(!cache_path.empty()) + return cache_path; + + const auto env_path = get_environment_path("XDG_CACHE_HOME"); + + if(env_path.empty()) { + cache_path = get_home_path() / ".cache"; + } + + create_missing_path(cache_path); + + return cache_path; +} + boost::filesystem::path filesystem::get_short_path(const boost::filesystem::path &path) noexcept { #ifdef _WIN32 return path; diff --git a/src/filesystem.hpp b/src/filesystem.hpp index 3f14e86..0ae47b6 100644 --- a/src/filesystem.hpp +++ b/src/filesystem.hpp @@ -4,6 +4,10 @@ #include class filesystem { +private: + static bool create_missing_path(const boost::filesystem::path &path) noexcept; + static boost::filesystem::path get_environment_path(const char *variable) noexcept; + public: static std::string read(const std::string &path); static std::string read(const boost::filesystem::path &path) { return read(path.string()); } @@ -16,7 +20,19 @@ public: static std::string escape_argument(const std::string &argument); static std::string unescape_argument(const std::string &argument); + /// Return the $HOME environment variable. If HOME is not set, then AppData + /// is returned. If neither HOME or AppData is set, then an empty path is + /// returned. static boost::filesystem::path get_home_path() noexcept; + /// Return the XDG_CONFIG_HOME environment variable if set. If + /// XDG_CONFIG_HOME is not set the default $HOME/.config is returned. + static const boost::filesystem::path &get_config_path() noexcept; + /// Return the XDG_CACHE_HOME environment variable if set. If XDG_CACHE_HOME + /// is not set the default $HOME/.cache is returned. + static const boost::filesystem::path &get_cache_path() noexcept; + /// Return the XDG_DATA_HOME environment variable if set. If XDG_DATA_HOME + /// is not set the default $HOME/.local/share is returned. + static const boost::filesystem::path &get_data_path() noexcept; /// Replaces home path with ~ static boost::filesystem::path get_short_path(const boost::filesystem::path &path) noexcept; /// Replaces ~ with home path (boost::filesystem does not recognize ~) diff --git a/tests/filesystem_test.cpp b/tests/filesystem_test.cpp index 166c852..59539cc 100644 --- a/tests/filesystem_test.cpp +++ b/tests/filesystem_test.cpp @@ -91,4 +91,22 @@ int main() { g_assert(uri == "file:///ro%20ot/te%20st%C3%A6%C3%B8%C3%A5.txt"); g_assert(path == filesystem::get_path_from_uri(uri)); } + + { + auto path = filesystem::get_cache_path(); + path = filesystem::get_short_path(path); + g_assert(path == "~/.cache"); + } + + { + auto path = filesystem::get_data_path(); + path = filesystem::get_short_path(path); + g_assert(path == "~/.local/share"); + } + + { + auto path = filesystem::get_config_path(); + path = filesystem::get_short_path(path); + g_assert(path == "~/.config"); + } }