From 9e96a19df49f0a229641c5dcc0bfb1dd192aa345 Mon Sep 17 00:00:00 2001 From: Rauli Laine Date: Sat, 7 Sep 2024 12:53:18 +0300 Subject: [PATCH] Use templates instead of inline functions --- .gitignore | 1 + LICENSE.md | 2 +- include/peelo/xdg.hpp | 70 +++++++++++++++++++++--------------- test/test_multiple_paths.cpp | 27 +++++++------- test/test_single_paths.cpp | 45 ++++++++++++++++------- 5 files changed, 91 insertions(+), 54 deletions(-) diff --git a/.gitignore b/.gitignore index 00a6291..a0ea4f1 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ /.vscode /build +/doxygen diff --git a/LICENSE.md b/LICENSE.md index 8b6c90f..5dc87e8 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -1,4 +1,4 @@ -Copyright (c) 2021, peelo.net +Copyright (c) 2021-2024, peelo.net All rights reserved. Redistribution and use in source and binary forms, with or without diff --git a/include/peelo/xdg.hpp b/include/peelo/xdg.hpp index e40a79d..29f88c6 100644 --- a/include/peelo/xdg.hpp +++ b/include/peelo/xdg.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, peelo.net + * Copyright (c) 2021-2024, peelo.net * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -40,31 +40,37 @@ namespace peelo::xdg { namespace internal { - inline std::vector - get_multiple_dirs(const char* env_variable_name) - { #if defined(_WIN32) - static const char separator = ';'; + static constexpr char path_separator = ';'; #else - static const char separator = ':'; + static constexpr char path_separator = ':'; #endif - std::vector result; - if (const auto env_variable = std::getenv(env_variable_name)) + template + std::vector + get_multiple_dirs(const char* env_variable_name) + { + std::vector result; + + if (auto begin = std::getenv(env_variable_name)) { - const std::string s = env_variable; - std::string::size_type start = 0; - std::string::size_type end = s.find(separator); + auto end = begin; - while (end != std::string::npos) + for (; *end; ++end) { - result.push_back(s.substr(start, end - start)); - start = end + 1; - end = s.find(separator, start); + if (*end != path_separator) + { + continue; + } + else if (end - begin > 0) + { + result.emplace_back(std::string(begin, end - begin)); + } + begin = end + 1; } - if (end - start > 0) + if (end - begin > 0) { - result.push_back(s.substr(start, end - start)); + result.emplace_back(std::string(begin, end - begin)); } } @@ -75,7 +81,8 @@ namespace peelo::xdg /** * Returns path to users home directory, if it can be determined. */ - inline std::optional + template + std::optional home_dir() { const auto home = std::getenv("HOME"); @@ -115,7 +122,8 @@ namespace peelo::xdg /** * Returns path to XDG data directory, if it can be determined. */ - inline std::optional + template + std::optional data_dir() { if (const auto env_variable = std::getenv("XDG_DATA_HOME")) @@ -134,7 +142,8 @@ namespace peelo::xdg * Returns all XDG data directories in users preferred order, or empty vector * if they cannot be determined. */ - inline std::vector + template + std::vector all_data_dirs() { auto result = internal::get_multiple_dirs("XDG_DATA_DIRS"); @@ -142,8 +151,8 @@ namespace peelo::xdg #if !defined(_WIN32) if (result.empty()) { - result.push_back("/usr/local/share"); - result.push_back("/usr/share"); + result.emplace_back("/usr/local/share"); + result.emplace_back("/usr/share"); } #endif @@ -153,7 +162,8 @@ namespace peelo::xdg /** * Returns path to XDG configuration directory, if it can be determined. */ - inline std::optional + template + std::optional config_dir() { if (const auto env_variable = std::getenv("XDG_CONFIG_HOME")) @@ -172,7 +182,8 @@ namespace peelo::xdg * Returns all XDG configuration directories in users preferred order, or * empty vector if they cannot be determined. */ - inline std::vector + template + std::vector all_config_dirs() { auto result = internal::get_multiple_dirs("XDG_CONFIG_DIRS"); @@ -180,7 +191,7 @@ namespace peelo::xdg #if !defined(_WIN32) if (result.empty()) { - result.push_back("/etc/xdg"); + result.emplace_back("/etc/xdg"); } #endif @@ -190,7 +201,8 @@ namespace peelo::xdg /** * Returns path to XDG state directory, if it can be determined. */ - inline std::optional + template + std::optional state_dir() { if (const auto env_variable = std::getenv("XDG_STATE_HOME")) @@ -208,7 +220,8 @@ namespace peelo::xdg /** * Returns path to XDG cache directory, if it can be determined. */ - inline std::optional + template + std::optional cache_dir() { if (const auto env_variable = std::getenv("XDG_CACHE_HOME")) @@ -226,7 +239,8 @@ namespace peelo::xdg /** * Returns path to XDG runtime directory, if it can be determined. */ - inline std::optional + template + std::optional runtime_dir() { if (const auto env_variable = std::getenv("XDG_RUNTIME_DIR")) diff --git a/test/test_multiple_paths.cpp b/test/test_multiple_paths.cpp index e64146e..7c5e007 100644 --- a/test/test_multiple_paths.cpp +++ b/test/test_multiple_paths.cpp @@ -4,23 +4,25 @@ #include -#if defined(_WIN32) -static const char separator = ';'; -#else -static const char separator = ':'; -#endif - using callback_type = std::function()>; -static void test_callback( +static void +test_callback( const callback_type& callback, const char* env_variable_name ) { + using peelo::xdg::internal::path_separator; + unsetenv(env_variable_name); setenv( env_variable_name, - (std::string("/xdg") + separator + "/xdg/xdg").c_str(), + ( + std::string("/xdg") + + path_separator + + path_separator + + "/xdg/xdg" + ).c_str(), 1 ); @@ -31,12 +33,11 @@ static void test_callback( assert(result[1] == std::filesystem::path("/xdg/xdg")); } -int main() +int +main() { using namespace peelo::xdg; - test_callback(all_data_dirs, "XDG_DATA_DIRS"); - test_callback(all_config_dirs, "XDG_CONFIG_DIRS"); - - return EXIT_SUCCESS; + test_callback(all_data_dirs, "XDG_DATA_DIRS"); + test_callback(all_config_dirs, "XDG_CONFIG_DIRS"); } diff --git a/test/test_single_paths.cpp b/test/test_single_paths.cpp index 49d7c25..84b3aa0 100644 --- a/test/test_single_paths.cpp +++ b/test/test_single_paths.cpp @@ -11,7 +11,8 @@ using std::optional; using callback_type = std::function()>; -static void test_with_env_variable( +static void +test_with_env_variable( const callback_type& callback, const char* env_variable_name ) @@ -24,7 +25,8 @@ static void test_with_env_variable( assert(*result == path("xdg") / "test"); } -static void test_without_env_variable( +static void +test_without_env_variable( const callback_type& callback, const char* env_variable_name, const optional& expected_result @@ -44,7 +46,8 @@ static void test_without_env_variable( } } -static void test_callback( +static void +test_callback( const callback_type& callback, const char* env_variable_name, const optional& expected_result_without_env_var = nullopt @@ -58,16 +61,34 @@ static void test_callback( ); } -int main() +int +main() { - const path base = "xdg"; using namespace peelo::xdg; + const path base = "xdg"; - test_callback(data_dir, "XDG_DATA_HOME", base / ".local" / "share"); - test_callback(config_dir, "XDG_CONFIG_HOME", base / ".config"); - test_callback(state_dir, "XDG_STATE_HOME", base / ".local" / "state"); - test_callback(cache_dir, "XDG_CACHE_HOME", base / ".cache"); - test_callback(runtime_dir, "XDG_RUNTIME_DIR"); - - return EXIT_SUCCESS; + test_callback( + data_dir, + "XDG_DATA_HOME", + base / ".local" / "share" + ); + test_callback( + config_dir, + "XDG_CONFIG_HOME", + base / ".config" + ); + test_callback( + state_dir, + "XDG_STATE_HOME", + base / ".local" / "state" + ); + test_callback( + cache_dir, + "XDG_CACHE_HOME", + base / ".cache" + ); + test_callback( + runtime_dir, + "XDG_RUNTIME_DIR" + ); }