Mercurial > code
annotate modules/xdg/xdg.hpp @ 559:5554ba5dc1dc
Xdg: style
author | David Demelier <markand@malikania.fr> |
---|---|
date | Tue, 21 Jun 2016 13:44:52 +0200 |
parents | f48bb09bccc7 |
children | 55f57b45a898 |
rev | line source |
---|---|
526 | 1 /* |
2 * xdg.hpp -- XDG directory specifications | |
3 * | |
4 * Copyright (c) 2013-2016 David Demelier <markand@malikania.fr> | |
5 * | |
6 * Permission to use, copy, modify, and/or distribute this software for any | |
7 * purpose with or without fee is hereby granted, provided that the above | |
8 * copyright notice and this permission notice appear in all copies. | |
9 * | |
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | |
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | |
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | |
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | |
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | |
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | |
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | |
17 */ | |
18 | |
19 #ifndef XDG_HPP | |
20 #define XDG_HPP | |
21 | |
22 /** | |
23 * \file xdg.hpp | |
24 * \brief XDG directory specifications. | |
25 * \author David Demelier <markand@malikana.fr> | |
26 */ | |
27 | |
28 #include <cstdlib> | |
29 #include <sstream> | |
30 #include <stdexcept> | |
31 #include <string> | |
32 #include <vector> | |
33 | |
34 /** | |
35 * \class Xdg | |
36 * \brief XDG directory specifications. | |
37 * | |
38 * Read and get XDG directories. | |
39 * | |
40 * This file should compiles on Windows to facilitate portability but its functions must not be used. | |
41 */ | |
42 class Xdg { | |
43 private: | |
548
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
526
diff
changeset
|
44 std::string m_configHome; |
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
526
diff
changeset
|
45 std::string m_dataHome; |
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
526
diff
changeset
|
46 std::string m_cacheHome; |
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
526
diff
changeset
|
47 std::string m_runtimeDir; |
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
526
diff
changeset
|
48 std::vector<std::string> m_configDirs; |
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
526
diff
changeset
|
49 std::vector<std::string> m_dataDirs; |
526 | 50 |
548
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
526
diff
changeset
|
51 bool isabsolute(const std::string &path) const noexcept |
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
526
diff
changeset
|
52 { |
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
526
diff
changeset
|
53 return path.length() > 0 && path[0] == '/'; |
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
526
diff
changeset
|
54 } |
526 | 55 |
548
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
526
diff
changeset
|
56 std::vector<std::string> split(const std::string &arg) const |
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
526
diff
changeset
|
57 { |
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
526
diff
changeset
|
58 std::stringstream iss(arg); |
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
526
diff
changeset
|
59 std::string item; |
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
526
diff
changeset
|
60 std::vector<std::string> elems; |
526 | 61 |
548
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
526
diff
changeset
|
62 while (std::getline(iss, item, ':')) |
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
526
diff
changeset
|
63 if (isabsolute(item)) |
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
526
diff
changeset
|
64 elems.push_back(item); |
526 | 65 |
548
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
526
diff
changeset
|
66 return elems; |
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
526
diff
changeset
|
67 } |
526 | 68 |
548
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
526
diff
changeset
|
69 std::string envOrHome(const std::string &var, const std::string &repl) const |
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
526
diff
changeset
|
70 { |
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
526
diff
changeset
|
71 auto value = std::getenv(var.c_str()); |
526 | 72 |
548
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
526
diff
changeset
|
73 if (value == nullptr || !isabsolute(value)) { |
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
526
diff
changeset
|
74 auto home = std::getenv("HOME"); |
526 | 75 |
548
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
526
diff
changeset
|
76 if (home == nullptr) |
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
526
diff
changeset
|
77 throw std::runtime_error("could not get home directory"); |
526 | 78 |
548
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
526
diff
changeset
|
79 return std::string(home) + "/" + repl; |
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
526
diff
changeset
|
80 } |
526 | 81 |
548
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
526
diff
changeset
|
82 return value; |
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
526
diff
changeset
|
83 } |
526 | 84 |
548
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
526
diff
changeset
|
85 std::vector<std::string> listOrDefaults(const std::string &var, const std::vector<std::string> &list) const |
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
526
diff
changeset
|
86 { |
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
526
diff
changeset
|
87 auto value = std::getenv(var.c_str()); |
526 | 88 |
548
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
526
diff
changeset
|
89 if (!value) |
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
526
diff
changeset
|
90 return list; |
526 | 91 |
548
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
526
diff
changeset
|
92 // No valid item at all? Use defaults. |
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
526
diff
changeset
|
93 auto result = split(value); |
526 | 94 |
548
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
526
diff
changeset
|
95 return (result.size() == 0) ? list : result; |
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
526
diff
changeset
|
96 } |
526 | 97 |
98 public: | |
548
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
526
diff
changeset
|
99 /** |
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
526
diff
changeset
|
100 * Open an xdg instance and load directories. |
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
526
diff
changeset
|
101 * |
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
526
diff
changeset
|
102 * \throw std::runtime_error on failures |
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
526
diff
changeset
|
103 */ |
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
526
diff
changeset
|
104 Xdg() |
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
526
diff
changeset
|
105 { |
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
526
diff
changeset
|
106 m_configHome = envOrHome("XDG_CONFIG_HOME", ".config"); |
559 | 107 m_dataHome = envOrHome("XDG_DATA_HOME", ".local/share"); |
108 m_cacheHome = envOrHome("XDG_CACHE_HOME", ".cache"); | |
526 | 109 |
548
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
526
diff
changeset
|
110 m_configDirs = listOrDefaults("XDG_CONFIG_DIRS", { "/etc/xdg" }); |
559 | 111 m_dataDirs = listOrDefaults("XDG_DATA_DIRS", { "/usr/local/share", "/usr/share" }); |
526 | 112 |
548
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
526
diff
changeset
|
113 /* |
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
526
diff
changeset
|
114 * Runtime directory is a special case and does not have a replacement, the application should manage |
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
526
diff
changeset
|
115 * this by itself. |
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
526
diff
changeset
|
116 */ |
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
526
diff
changeset
|
117 auto runtime = std::getenv("XDG_RUNTIME_DIR"); |
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
526
diff
changeset
|
118 if (runtime && isabsolute(runtime)) |
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
526
diff
changeset
|
119 m_runtimeDir = runtime; |
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
526
diff
changeset
|
120 } |
526 | 121 |
548
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
526
diff
changeset
|
122 /** |
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
526
diff
changeset
|
123 * Get the config directory. ${XDG_CONFIG_HOME} or ${HOME}/.config |
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
526
diff
changeset
|
124 * |
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
526
diff
changeset
|
125 * \return the config directory |
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
526
diff
changeset
|
126 */ |
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
526
diff
changeset
|
127 inline const std::string &configHome() const noexcept |
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
526
diff
changeset
|
128 { |
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
526
diff
changeset
|
129 return m_configHome; |
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
526
diff
changeset
|
130 } |
526 | 131 |
548
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
526
diff
changeset
|
132 /** |
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
526
diff
changeset
|
133 * Get the data directory. ${XDG_DATA_HOME} or ${HOME}/.local/share |
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
526
diff
changeset
|
134 * |
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
526
diff
changeset
|
135 * \return the data directory |
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
526
diff
changeset
|
136 */ |
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
526
diff
changeset
|
137 inline const std::string &dataHome() const noexcept |
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
526
diff
changeset
|
138 { |
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
526
diff
changeset
|
139 return m_dataHome; |
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
526
diff
changeset
|
140 } |
526 | 141 |
548
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
526
diff
changeset
|
142 /** |
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
526
diff
changeset
|
143 * Get the cache directory. ${XDG_CACHE_HOME} or ${HOME}/.cache |
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
526
diff
changeset
|
144 * |
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
526
diff
changeset
|
145 * \return the cache directory |
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
526
diff
changeset
|
146 */ |
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
526
diff
changeset
|
147 inline const std::string &cacheHome() const noexcept |
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
526
diff
changeset
|
148 { |
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
526
diff
changeset
|
149 return m_cacheHome; |
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
526
diff
changeset
|
150 } |
526 | 151 |
548
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
526
diff
changeset
|
152 /** |
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
526
diff
changeset
|
153 * Get the runtime directory. |
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
526
diff
changeset
|
154 * |
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
526
diff
changeset
|
155 * There is no replacement for XDG_RUNTIME_DIR, if it is not set, an empty valus is returned and the user is |
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
526
diff
changeset
|
156 * responsible of using something else. |
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
526
diff
changeset
|
157 * |
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
526
diff
changeset
|
158 * \return the runtime directory |
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
526
diff
changeset
|
159 */ |
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
526
diff
changeset
|
160 inline const std::string &runtimeDir() const noexcept |
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
526
diff
changeset
|
161 { |
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
526
diff
changeset
|
162 return m_runtimeDir; |
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
526
diff
changeset
|
163 } |
526 | 164 |
548
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
526
diff
changeset
|
165 /** |
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
526
diff
changeset
|
166 * Get the standard config directories. ${XDG_CONFIG_DIRS} or { "/etc/xdg" } |
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
526
diff
changeset
|
167 * |
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
526
diff
changeset
|
168 * \return the list of config directories |
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
526
diff
changeset
|
169 */ |
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
526
diff
changeset
|
170 inline const std::vector<std::string> &configDirs() const noexcept |
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
526
diff
changeset
|
171 { |
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
526
diff
changeset
|
172 return m_configDirs; |
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
526
diff
changeset
|
173 } |
526 | 174 |
548
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
526
diff
changeset
|
175 /** |
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
526
diff
changeset
|
176 * Get the data directories. ${XDG_DATA_DIRS} or { "/usr/local/share", "/usr/share" } |
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
526
diff
changeset
|
177 * |
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
526
diff
changeset
|
178 * \return the list of data directories |
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
526
diff
changeset
|
179 */ |
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
526
diff
changeset
|
180 inline const std::vector<std::string> &dataDirs() const noexcept |
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
526
diff
changeset
|
181 { |
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
526
diff
changeset
|
182 return m_dataDirs; |
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
526
diff
changeset
|
183 } |
526 | 184 }; |
185 | |
186 #endif // !XDG_HPP |