Mercurial > code
annotate modules/xdg/xdg.hpp @ 585:55f57b45a898
Xdg: reduce column limit
author | David Demelier <markand@malikania.fr> |
---|---|
date | Wed, 20 Jul 2016 17:09:20 +0200 |
parents | 5554ba5dc1dc |
children | ff11ca6b0d55 |
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 * | |
585
55f57b45a898
Xdg: reduce column limit
David Demelier <markand@malikania.fr>
parents:
559
diff
changeset
|
40 * This file should compiles on Windows to facilitate portability but its |
55f57b45a898
Xdg: reduce column limit
David Demelier <markand@malikania.fr>
parents:
559
diff
changeset
|
41 * functions must not be used. |
526 | 42 */ |
43 class Xdg { | |
44 private: | |
548
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
526
diff
changeset
|
45 std::string m_configHome; |
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
526
diff
changeset
|
46 std::string m_dataHome; |
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
526
diff
changeset
|
47 std::string m_cacheHome; |
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
526
diff
changeset
|
48 std::string m_runtimeDir; |
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
526
diff
changeset
|
49 std::vector<std::string> m_configDirs; |
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
526
diff
changeset
|
50 std::vector<std::string> m_dataDirs; |
526 | 51 |
548
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
526
diff
changeset
|
52 bool isabsolute(const std::string &path) const noexcept |
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
526
diff
changeset
|
53 { |
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
526
diff
changeset
|
54 return path.length() > 0 && path[0] == '/'; |
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
526
diff
changeset
|
55 } |
526 | 56 |
548
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
526
diff
changeset
|
57 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
|
58 { |
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
526
diff
changeset
|
59 std::stringstream iss(arg); |
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
526
diff
changeset
|
60 std::string item; |
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
526
diff
changeset
|
61 std::vector<std::string> elems; |
526 | 62 |
548
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
526
diff
changeset
|
63 while (std::getline(iss, item, ':')) |
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
526
diff
changeset
|
64 if (isabsolute(item)) |
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
526
diff
changeset
|
65 elems.push_back(item); |
526 | 66 |
548
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
526
diff
changeset
|
67 return elems; |
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
526
diff
changeset
|
68 } |
526 | 69 |
548
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
526
diff
changeset
|
70 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
|
71 { |
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
526
diff
changeset
|
72 auto value = std::getenv(var.c_str()); |
526 | 73 |
548
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
526
diff
changeset
|
74 if (value == nullptr || !isabsolute(value)) { |
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
526
diff
changeset
|
75 auto home = std::getenv("HOME"); |
526 | 76 |
548
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
526
diff
changeset
|
77 if (home == nullptr) |
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
526
diff
changeset
|
78 throw std::runtime_error("could not get home directory"); |
526 | 79 |
548
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
526
diff
changeset
|
80 return std::string(home) + "/" + repl; |
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
526
diff
changeset
|
81 } |
526 | 82 |
548
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
526
diff
changeset
|
83 return value; |
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
526
diff
changeset
|
84 } |
526 | 85 |
585
55f57b45a898
Xdg: reduce column limit
David Demelier <markand@malikania.fr>
parents:
559
diff
changeset
|
86 std::vector<std::string> listOrDefaults(const std::string &var, |
55f57b45a898
Xdg: reduce column limit
David Demelier <markand@malikania.fr>
parents:
559
diff
changeset
|
87 const std::vector<std::string> &list) const |
548
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
526
diff
changeset
|
88 { |
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
526
diff
changeset
|
89 auto value = std::getenv(var.c_str()); |
526 | 90 |
548
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
526
diff
changeset
|
91 if (!value) |
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
526
diff
changeset
|
92 return list; |
526 | 93 |
548
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
526
diff
changeset
|
94 // No valid item at all? Use defaults. |
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
526
diff
changeset
|
95 auto result = split(value); |
526 | 96 |
548
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
526
diff
changeset
|
97 return (result.size() == 0) ? list : result; |
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
526
diff
changeset
|
98 } |
526 | 99 |
100 public: | |
548
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 * Open an xdg instance and load directories. |
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 * \throw std::runtime_error on failures |
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 Xdg() |
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
526
diff
changeset
|
107 { |
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
526
diff
changeset
|
108 m_configHome = envOrHome("XDG_CONFIG_HOME", ".config"); |
559 | 109 m_dataHome = envOrHome("XDG_DATA_HOME", ".local/share"); |
110 m_cacheHome = envOrHome("XDG_CACHE_HOME", ".cache"); | |
526 | 111 |
548
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
526
diff
changeset
|
112 m_configDirs = listOrDefaults("XDG_CONFIG_DIRS", { "/etc/xdg" }); |
559 | 113 m_dataDirs = listOrDefaults("XDG_DATA_DIRS", { "/usr/local/share", "/usr/share" }); |
526 | 114 |
548
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
526
diff
changeset
|
115 /* |
585
55f57b45a898
Xdg: reduce column limit
David Demelier <markand@malikania.fr>
parents:
559
diff
changeset
|
116 * Runtime directory is a special case and does not have a replacement, |
55f57b45a898
Xdg: reduce column limit
David Demelier <markand@malikania.fr>
parents:
559
diff
changeset
|
117 * the application should manage this by itself. |
548
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
526
diff
changeset
|
118 */ |
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
526
diff
changeset
|
119 auto runtime = std::getenv("XDG_RUNTIME_DIR"); |
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
526
diff
changeset
|
120 if (runtime && isabsolute(runtime)) |
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
526
diff
changeset
|
121 m_runtimeDir = runtime; |
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
526
diff
changeset
|
122 } |
526 | 123 |
548
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 * 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
|
126 * |
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
526
diff
changeset
|
127 * \return the config directory |
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 inline const std::string &configHome() const noexcept |
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
526
diff
changeset
|
130 { |
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
526
diff
changeset
|
131 return m_configHome; |
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
526
diff
changeset
|
132 } |
526 | 133 |
548
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 * 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
|
136 * |
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
526
diff
changeset
|
137 * \return the data directory |
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 inline const std::string &dataHome() const noexcept |
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
526
diff
changeset
|
140 { |
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
526
diff
changeset
|
141 return m_dataHome; |
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
526
diff
changeset
|
142 } |
526 | 143 |
548
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 * 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
|
146 * |
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
526
diff
changeset
|
147 * \return the cache directory |
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 inline const std::string &cacheHome() const noexcept |
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
526
diff
changeset
|
150 { |
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
526
diff
changeset
|
151 return m_cacheHome; |
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
526
diff
changeset
|
152 } |
526 | 153 |
548
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 * Get the runtime directory. |
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
526
diff
changeset
|
156 * |
585
55f57b45a898
Xdg: reduce column limit
David Demelier <markand@malikania.fr>
parents:
559
diff
changeset
|
157 * There is no replacement for XDG_RUNTIME_DIR, if it is not set, an empty |
55f57b45a898
Xdg: reduce column limit
David Demelier <markand@malikania.fr>
parents:
559
diff
changeset
|
158 * value is returned and the user is responsible of using something else. |
548
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 * \return the runtime directory |
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 inline const std::string &runtimeDir() const noexcept |
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
526
diff
changeset
|
163 { |
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
526
diff
changeset
|
164 return m_runtimeDir; |
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
526
diff
changeset
|
165 } |
526 | 166 |
548
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 * 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
|
169 * |
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
526
diff
changeset
|
170 * \return the list of config directories |
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 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
|
173 { |
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
526
diff
changeset
|
174 return m_configDirs; |
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
526
diff
changeset
|
175 } |
526 | 176 |
548
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
526
diff
changeset
|
177 /** |
585
55f57b45a898
Xdg: reduce column limit
David Demelier <markand@malikania.fr>
parents:
559
diff
changeset
|
178 * Get the data directories. ${XDG_DATA_DIRS} or { "/usr/local/share", |
55f57b45a898
Xdg: reduce column limit
David Demelier <markand@malikania.fr>
parents:
559
diff
changeset
|
179 * "/usr/share" } |
548
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
526
diff
changeset
|
180 * |
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
526
diff
changeset
|
181 * \return the list of data directories |
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
526
diff
changeset
|
182 */ |
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
526
diff
changeset
|
183 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
|
184 { |
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
526
diff
changeset
|
185 return m_dataDirs; |
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
526
diff
changeset
|
186 } |
526 | 187 }; |
188 | |
189 #endif // !XDG_HPP |