2 * Copyright © 2012 Intel Corporation
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21 * DEALINGS IN THE SOFTWARE.
23 * Author: Daniel Stone <daniel@fooishbar.org>
35 /* keeps a cache of all makedir/maketmpdir directories so we can free and
36 * rmdir them in one go, see unmakedirs() */
40 /* keeps a cache of all buffered env vars so we can restore
41 * them in one go, see restore_env() */
48 static void buffer_env(const char *key)
50 char *v = getenv(key);
52 environment[nenviron].key = strdup(key);
53 environment[nenviron].value = v ? strdup(v) : NULL;
57 static void restore_env(void)
59 for (int i = 0; i < nenviron; i++) {
60 char *key = environment[i].key,
61 *value = environment[i].value;
64 setenv(key, value, 1);
72 memset(environment, 0, sizeof(environment));
75 static const char *makedir(const char *parent, const char *path)
80 err = asprintf(&dirname, "%s/%s", parent, path);
82 err = mkdir(dirname, 0777);
85 dirnames[ndirs++] = dirname;
90 static const char *maketmpdir(void)
92 const char *template = "/tmp/xkbcommon-test.XXXXXX";
93 char *tmpdir = strdup(template);
95 tmpdir = mkdtemp(tmpdir);
96 assert(tmpdir != NULL);
98 dirnames[ndirs++] = tmpdir;
103 static void unmakedirs(void)
105 /* backwards order for rmdir to work */
106 for (int i = ndirs - 1; i >= 0; i--) {
107 char *dir = dirnames[i];
114 memset(dirnames, 0, sizeof(dirnames));
118 test_config_root_include_path(void)
120 struct xkb_context *ctx;
122 const char *context_path;
125 buffer_env("XKB_CONFIG_ROOT");
127 buffer_env("XDG_CONFIG_HOME");
129 tmpdir = maketmpdir();
130 setenv("XKB_CONFIG_ROOT", tmpdir, 1);
132 unsetenv("XDG_CONFIG_HOME");
134 /* built-in path is last */
135 ctx = xkb_context_new(XKB_CONTEXT_NO_FLAGS);
136 nincludes = xkb_context_num_include_paths(ctx);
137 assert(nincludes >= 1);
138 context_path = xkb_context_include_path_get(ctx, nincludes - 1);
139 assert(strcmp(context_path, tmpdir) == 0);
140 xkb_context_unref(ctx);
147 test_config_root_include_path_fallback(void)
149 struct xkb_context *ctx;
150 const char *xkbdir = DFLT_XKB_CONFIG_ROOT;
151 const char *context_path;
155 /* quick and dirty check that the default directory exists.
156 * It may not on a vanilla test box if we just run the test
157 * suite, so where it's not there just skip this test. */
158 dir = opendir(xkbdir);
163 buffer_env("XKB_CONFIG_ROOT");
165 buffer_env("XDG_CONFIG_HOME");
167 unsetenv("XKB_CONFIG_ROOT");
169 unsetenv("XDG_CONFIG_HOME");
171 /* built-in path is last */
172 ctx = xkb_context_new(XKB_CONTEXT_NO_FLAGS);
173 nincludes = xkb_context_num_include_paths(ctx);
174 assert(nincludes >= 1);
175 context_path = xkb_context_include_path_get(ctx, nincludes - 1);
176 assert(strcmp(context_path, xkbdir) == 0);
177 xkb_context_unref(ctx);
184 test_xkbdir_include_path(void)
186 struct xkb_context *ctx;
188 const char *xkb_path;
189 const char *context_path;
192 buffer_env("XDG_CONFIG_HOME");
194 tmpdir = maketmpdir();
195 xkb_path = makedir(tmpdir, ".xkb");
196 setenv("HOME", tmpdir, 1);
197 setenv("XDG_CONFIG_HOME", tmpdir, 1);
199 /* No XDG directory in our tmpdir, so we expect
200 * the $HOME/.xkb to be the first include path */
201 ctx = xkb_context_new(XKB_CONTEXT_NO_FLAGS);
202 assert(xkb_context_num_include_paths(ctx) >= 1);
203 context_path = xkb_context_include_path_get(ctx, 0);
204 assert(strcmp(context_path, xkb_path) == 0);
205 xkb_context_unref(ctx);
212 test_xdg_include_path(void)
214 struct xkb_context *ctx;
216 const char *xdg_path;
217 const char *context_path;
219 buffer_env("XDG_CONFIG_HOME");
221 tmpdir = maketmpdir();
222 xdg_path = makedir(tmpdir, "xkb");
223 setenv("XDG_CONFIG_HOME", tmpdir, 1);
225 /* XDG path is always first */
226 ctx = xkb_context_new(XKB_CONTEXT_NO_FLAGS);
227 assert(xkb_context_num_include_paths(ctx) >= 1);
228 context_path = xkb_context_include_path_get(ctx, 0);
229 assert(strcmp(context_path, xdg_path) == 0);
230 xkb_context_unref(ctx);
237 test_xdg_include_path_fallback(void)
239 struct xkb_context *ctx;
241 const char *xdg_root, *xdg_path;
242 const char *context_path;
244 buffer_env("XDG_CONFIG_HOME");
247 tmpdir = maketmpdir();
248 xdg_root = makedir(tmpdir, ".config");
249 xdg_path = makedir(xdg_root, "xkb");
250 setenv("HOME", tmpdir, 1);
251 unsetenv("XDG_CONFIG_HOME");
253 /* XDG path is always first, even if fallback */
254 ctx = xkb_context_new(XKB_CONTEXT_NO_FLAGS);
255 assert(xkb_context_num_include_paths(ctx) >= 1);
256 context_path = xkb_context_include_path_get(ctx, 0);
257 assert(strcmp(context_path, xdg_path) == 0);
258 xkb_context_unref(ctx);
265 test_include_order(void)
267 struct xkb_context *ctx;
269 const char *xdg_path;
270 const char *xkb_home_path;
271 const char *xkb_root_path;
272 const char *context_path;
274 buffer_env("XKB_CONFIG_ROOT");
275 buffer_env("XDG_CONFIG_HOME");
278 tmpdir = maketmpdir();
279 xdg_path = makedir(tmpdir, "xkb");
280 xkb_home_path = makedir(tmpdir, ".xkb");
281 xkb_root_path = makedir(tmpdir, "xkbroot");
282 setenv("HOME", tmpdir, 1);
283 setenv("XDG_CONFIG_HOME", tmpdir, 1);
284 setenv("XKB_CONFIG_ROOT", xkb_root_path, 1);
286 ctx = xkb_context_new(XKB_CONTEXT_NO_FLAGS);
287 assert(xkb_context_num_include_paths(ctx) >= 3);
289 context_path = xkb_context_include_path_get(ctx, 0);
290 assert(strcmp(context_path, xdg_path) == 0);
291 /* $HOME/.xkb is second */
292 context_path = xkb_context_include_path_get(ctx, 1);
293 assert(strcmp(context_path, xkb_home_path) == 0);
294 /* CONFIG_ROOT is last */
295 context_path = xkb_context_include_path_get(ctx, 2);
296 assert(strcmp(context_path, xkb_root_path) == 0);
298 xkb_context_unref(ctx);
307 struct xkb_context *context = test_get_context(0);
312 assert(xkb_context_num_include_paths(context) == 1);
313 assert(!xkb_context_include_path_append(context, "¡NONSENSE!"));
314 assert(xkb_context_num_include_paths(context) == 1);
316 atom = xkb_atom_intern(context, "HELLOjunkjunkjunk", 5);
317 assert(atom != XKB_ATOM_NONE);
318 assert(streq(xkb_atom_text(context, atom), "HELLO"));
320 atom = xkb_atom_intern_literal(context, "HELLOjunkjunkjunk");
321 assert(atom != XKB_ATOM_NONE);
322 assert(streq(xkb_atom_text(context, atom), "HELLOjunkjunkjunk"));
324 xkb_context_unref(context);
326 test_config_root_include_path();
327 test_config_root_include_path_fallback();
328 test_xkbdir_include_path();
329 test_xdg_include_path();
330 test_xdg_include_path_fallback();
331 test_include_order();