# HG changeset patch # User David Demelier # Date 1482842382 -3600 # Node ID ab758b6bfdc740d5b4dbf209d4c2bf6c19a53e0a # Parent 0f9db77f5aa5cb3f86711014071ad27c3750e968 Xdg: move to hg.markand.fr/libxdg diff -r 0f9db77f5aa5 -r ab758b6bfdc7 CMakeLists.txt --- a/CMakeLists.txt Tue Dec 27 13:37:04 2016 +0100 +++ b/CMakeLists.txt Tue Dec 27 13:39:42 2016 +0100 @@ -50,6 +50,4 @@ endif () add_subdirectory(modules/js) -add_subdirectory(modules/xdg) - add_subdirectory(misc) diff -r 0f9db77f5aa5 -r ab758b6bfdc7 modules/xdg/CMakeLists.txt --- a/modules/xdg/CMakeLists.txt Tue Dec 27 13:37:04 2016 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,24 +0,0 @@ -# -# CMakeLists.txt -- code building for common code -# -# Copyright (c) 2013-2016 David Demelier -# -# Permission to use, copy, modify, and/or distribute this software for any -# purpose with or without fee is hereby granted, provided that the above -# copyright notice and this permission notice appear in all copies. -# -# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -# - -if (NOT WIN32) - code_define_module( - NAME xdg - SOURCES xdg.hpp - ) -endif () diff -r 0f9db77f5aa5 -r ab758b6bfdc7 modules/xdg/doc/mainpage.cpp --- a/modules/xdg/doc/mainpage.cpp Tue Dec 27 13:37:04 2016 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,13 +0,0 @@ -/** - * \mainpage - * - * Welcome to the xdg library. - * - * ## Introduction - * - * Extract freedesktop's XDG directory specifications. - * - * ## Installation - * - * Just copy the file xdg.hpp and it them to your project. - */ diff -r 0f9db77f5aa5 -r ab758b6bfdc7 modules/xdg/test/main.cpp --- a/modules/xdg/test/main.cpp Tue Dec 27 13:37:04 2016 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,274 +0,0 @@ -/* - * main.cpp -- main test file for XDG - * - * Copyright (c) 2013-2016 David Demelier - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include - -#include - -using namespace testing; - -namespace { - -std::string myhome; - -} // !namespace - -#if defined(_WIN32) - -inline bool unsetenv(std::string name) -{ - name += "="; - - _putenv(name.c_str()); - - return true; -} - -inline bool setenv(const std::string& name, const std::string& value, bool) -{ - std::string t = name + "=" + value; - - _putenv(t.c_str()); - - return true; -} - -#endif - -TEST(HomeEmpty, config) -{ - ASSERT_TRUE(unsetenv("XDG_CONFIG_HOME") == 0); - - xdg xdg; - - ASSERT_EQ(myhome + "/.config", xdg.config_home()); -} - -TEST(HomeEmpty, data) -{ - ASSERT_TRUE(unsetenv("XDG_DATA_HOME") == 0); - - xdg xdg; - - ASSERT_EQ(myhome + "/.local/share", xdg.data_home()); -} - -TEST(HomeEmpty, cache) -{ - ASSERT_TRUE(unsetenv("XDG_CACHE_HOME") == 0); - - xdg xdg; - - ASSERT_EQ(myhome + "/.cache", xdg.cache_home()); -} - -TEST(HomeEmpty, runtime) -{ - ASSERT_TRUE(unsetenv("XDG_RUNTIME_DIR") == 0); - - xdg xdg; - - ASSERT_TRUE(xdg.runtime_dir().empty()); -} - -TEST(HomeValid, config) -{ - ASSERT_TRUE(setenv("XDG_CONFIG_HOME", "/test/config", true) == 0); - - xdg xdg; - - ASSERT_EQ("/test/config", xdg.config_home()); -} - -TEST(HomeValid, data) -{ - ASSERT_TRUE(setenv("XDG_DATA_HOME", "/test/data", true) == 0); - - xdg xdg; - - ASSERT_EQ("/test/data", xdg.data_home()); -} - -TEST(HomeValid, cache) -{ - ASSERT_TRUE(setenv("XDG_CACHE_HOME", "/test/cache", true) == 0); - - xdg xdg; - - ASSERT_EQ("/test/cache", xdg.cache_home()); -} - -TEST(HomeValid, runtime) -{ - ASSERT_TRUE(setenv("XDG_RUNTIME_DIR", "/test/runtime", true) == 0); - - xdg xdg; - - ASSERT_EQ("/test/runtime", xdg.runtime_dir()); -} - -TEST(HomeInvalid, config) -{ - ASSERT_TRUE(setenv("XDG_CONFIG_HOME", "invalid", true) == 0); - - xdg xdg; - - ASSERT_EQ(myhome + "/.config", xdg.config_home()); -} - -TEST(HomeInvalid, data) -{ - ASSERT_TRUE(setenv("XDG_DATA_HOME", "invalid", true) == 0); - - xdg xdg; - - ASSERT_EQ(myhome + "/.local/share", xdg.data_home()); -} - -TEST(HomeInvalid, cache) -{ - ASSERT_TRUE(setenv("XDG_CACHE_HOME", "invalid", true) == 0); - - xdg xdg; - - ASSERT_EQ(myhome + "/.cache", xdg.cache_home()); -} - -TEST(HomeInvalid, runtime) -{ - ASSERT_TRUE(setenv("XDG_RUNTIME_DIR", "invalid", true) == 0); - - xdg xdg; - - ASSERT_TRUE(xdg.runtime_dir().empty()); -} - -TEST(DirectoriesEmpty, config) -{ - ASSERT_TRUE(unsetenv("XDG_CONFIG_DIRS") == 0); - - xdg xdg; - - const auto &list = xdg.config_dirs(); - - ASSERT_EQ((size_t)1, list.size()); - ASSERT_EQ("/etc/xdg", list[0]); -} - -TEST(DirectoriesEmpty, data) -{ - ASSERT_TRUE(unsetenv("XDG_DATA_DIRS") == 0); - - xdg xdg; - - const auto &list = xdg.data_dirs(); - - ASSERT_EQ((size_t)2, list.size()); - ASSERT_EQ("/usr/local/share", list[0]); - ASSERT_EQ("/usr/share", list[1]); -} - -TEST(DirectoriesValid, config) -{ - ASSERT_TRUE(setenv("XDG_CONFIG_DIRS", "/config1:/config2", true) == 0); - - xdg xdg; - - const auto &list = xdg.config_dirs(); - - ASSERT_EQ((size_t)2, list.size()); - ASSERT_EQ("/config1", list[0]); - ASSERT_EQ("/config2", list[1]); -} - -TEST(DirectoriesValid, data) -{ - ASSERT_TRUE(setenv("XDG_DATA_DIRS", "/data1:/data2", true) == 0); - - xdg xdg; - - const auto &list = xdg.data_dirs(); - - ASSERT_EQ((size_t)2, list.size()); - ASSERT_EQ("/data1", list[0]); - ASSERT_EQ("/data2", list[1]); -} - -TEST(DirectoriesInvalid, config) -{ - ASSERT_TRUE(setenv("XDG_CONFIG_DIRS", "bad1:bad2", true) == 0); - - xdg xdg; - - const auto &list = xdg.config_dirs(); - - ASSERT_EQ((size_t)1, list.size()); - ASSERT_EQ("/etc/xdg", list[0]); -} - -TEST(DirectoriesInvalid, data) -{ - ASSERT_TRUE(setenv("XDG_DATA_DIRS", "bad1:bad2", true) == 0); - - xdg xdg; - - const auto &list = xdg.data_dirs(); - - ASSERT_EQ((size_t)2, list.size()); - ASSERT_EQ("/usr/local/share", list[0]); - ASSERT_EQ("/usr/share", list[1]); -} - -TEST(DirectoriesMixed, config) -{ - ASSERT_TRUE(setenv("XDG_CONFIG_DIRS", "/config1:bad:/config2", true) == 0); - - xdg xdg; - - const auto &list = xdg.config_dirs(); - - ASSERT_EQ((size_t)2, list.size()); - ASSERT_EQ("/config1", list[0]); - ASSERT_EQ("/config2", list[1]); -} - -TEST(DirectoriesMixed, data) -{ - ASSERT_TRUE(setenv("XDG_DATA_DIRS", "/data1:bad:/data2", true) == 0); - - xdg xdg; - - const auto &list = xdg.data_dirs(); - - ASSERT_EQ((size_t)2, list.size()); - ASSERT_EQ("/data1", list[0]); - ASSERT_EQ("/data2", list[1]); -} - -int main(int argc, char **argv) -{ - auto home = getenv("HOME"); - - if (home == nullptr) - return 0; - - myhome = home; - InitGoogleTest(&argc, argv); - - return RUN_ALL_TESTS(); -} diff -r 0f9db77f5aa5 -r ab758b6bfdc7 modules/xdg/xdg.hpp --- a/modules/xdg/xdg.hpp Tue Dec 27 13:37:04 2016 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,194 +0,0 @@ -/* - * xdg.hpp -- XDG directory specifications - * - * Copyright (c) 2013-2016 David Demelier - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef XDG_HPP -#define XDG_HPP - -/** - * \file xdg.hpp - * \brief XDG directory specifications. - * \author David Demelier - */ - -#include -#include -#include -#include -#include - -/** - * \brief XDG directory specifications. - * - * Read and get XDG directories. - * - * This file should compiles on Windows to facilitate portability but its - * functions must not be used. - */ -class xdg { -private: - std::string m_config_home; - std::string m_data_home; - std::string m_cache_home; - std::string m_runtime_dir; - std::vector m_config_dirs; - std::vector m_data_dirs; - - inline bool is_absolute(const std::string& path) const noexcept - { - return path.length() > 0 && path[0] == '/'; - } - - std::vector split(const std::string& arg) const - { - std::stringstream iss(arg); - std::string item; - std::vector elems; - - while (std::getline(iss, item, ':')) { - if (is_absolute(item)) { - elems.push_back(item); - } - } - - return elems; - } - - std::string env_or_home(const std::string& var, const std::string& repl) const - { - auto value = std::getenv(var.c_str()); - - if (value == nullptr || !is_absolute(value)) { - auto home = std::getenv("HOME"); - - if (home == nullptr) { - throw std::runtime_error("could not get home directory"); - } - - return std::string(home) + "/" + repl; - } - - return value; - } - - std::vector list_or_defaults(const std::string& var, - const std::vector& list) const - { - auto value = std::getenv(var.c_str()); - - if (!value) { - return list; - } - - // No valid item at all? Use defaults. - auto result = split(value); - - return (result.size() == 0) ? list : result; - } - -public: - /** - * Open an xdg instance and load directories. - * - * \throw std::runtime_error on failures - */ - xdg() - { - m_config_home = env_or_home("XDG_CONFIG_HOME", ".config"); - m_data_home = env_or_home("XDG_DATA_HOME", ".local/share"); - m_cache_home = env_or_home("XDG_CACHE_HOME", ".cache"); - - m_config_dirs = list_or_defaults("XDG_CONFIG_DIRS", { "/etc/xdg" }); - m_data_dirs = list_or_defaults("XDG_DATA_DIRS", { "/usr/local/share", "/usr/share" }); - - /* - * Runtime directory is a special case and does not have a replacement, - * the application should manage this by itself. - */ - auto runtime = std::getenv("XDG_RUNTIME_DIR"); - - if (runtime && is_absolute(runtime)) { - m_runtime_dir = runtime; - } - } - - /** - * Get the config directory. ${XDG_CONFIG_HOME} or ${HOME}/.config - * - * \return the config directory - */ - inline const std::string& config_home() const noexcept - { - return m_config_home; - } - - /** - * Get the data directory. ${XDG_DATA_HOME} or ${HOME}/.local/share - * - * \return the data directory - */ - inline const std::string& data_home() const noexcept - { - return m_data_home; - } - - /** - * Get the cache directory. ${XDG_CACHE_HOME} or ${HOME}/.cache - * - * \return the cache directory - */ - inline const std::string& cache_home() const noexcept - { - return m_cache_home; - } - - /** - * Get the runtime directory. - * - * There is no replacement for XDG_RUNTIME_DIR, if it is not set, an empty - * value is returned and the user is responsible of using something else. - * - * \return the runtime directory - */ - inline const std::string& runtime_dir() const noexcept - { - return m_runtime_dir; - } - - /** - * Get the standard config directories. ${XDG_CONFIG_DIRS} or { "/etc/xdg" } - * - * \return the list of config directories - */ - inline const std::vector& config_dirs() const noexcept - { - return m_config_dirs; - } - - /** - * Get the data directories. ${XDG_DATA_DIRS} or { "/usr/local/share", - * "/usr/share" } - * - * \return the list of data directories - */ - inline const std::vector& data_dirs() const noexcept - { - return m_data_dirs; - } -}; - -#endif // !XDG_HPP